【问题标题】:Using generic class as property of non-generic class C#使用泛型类作为非泛型类 C# 的属性
【发布时间】:2017-12-31 03:51:42
【问题描述】:

假设我有以下两个课程,理想情况下可以做我想做的事:

Foo.cs:

public class Foo
{
    private int Type { get; set; } = 0;

    public FooHelper FooHelper
    {
        get
        {
            switch (Type)
            {
                case 1:
                    return new FooHelper<Guid>("Foo", "Bar", "foobar", "", Guid.NewGuid());
                case 2:
                default:
                    return new FooHelper<int>("Bar", "Foo", "", "", 11);
            }
        }
    }

    public Foo(int type)
    {
        Type = type;
    }
}

FooHelper.cs:

public class FooHelper<T> where T : struct
{
    public string Controller { get; set; }    = string.Empty;
    public string Action { get; set; }        = string.Empty;
    public string Area { get; set; }          = string.Empty;
    public string NameParameter { get; set; } = string.Empty;
    public T IdParameter { get; set; }        = default(T);

    public FooHelper() { }
    public FooHelper(string controller, string action, string area, string name, T id)
    {
        Controller    = controller;
        Action        = action;
        Area          = area;
        NameParameter = name;
        IdParameter   = id;
    }
}

根据作为非泛型类 Foo 的构造函数的参数传入的整数值,属性 FooHelper 返回基于泛型类 FooHelper 的新实例一个 Guid 或一个 int。

但是,如果不使 Foo 也通用,我似乎无法完成这项工作,这是我不想要的。我得到的错误是在 FooHelper 的属性线上,说明:

Using the generic type 'FooHelper&lt;T&gt;' requires 1 type arguments

这是有道理的,但我当时不知道。我想在 Foo 的构造函数中确定 FooHelper 的类型。

是我遗漏了什么,还是在这种情况下无法做我想做的事?

【问题讨论】:

  • 我没有看到任何 'ProfileHelper'
  • 你知道你的泛型类对 T 有约束吗? (where T: struct)?
  • 这与 op 的问题并不真正相关,因为他的代码 @RomanAnanyev 目前没有任何问题

标签: c# generics


【解决方案1】:

问题是 public FooHelper FooHelper 甚至不会编译,因为没有名为 FooHelper 的类型。然而,FooHelper&lt;int&gt;FooHelper&lt;Guid&gt; 却没有任何共同之处。因此,这个问题(再次)是由于您在运行时提供信息(类型切换)并期望编译器在编译时推断出正确的泛型类型,这是不可能的。

您可以做的是创建一个非泛型接口,从您的所有助手派生的以及您的方法返回的接口:

public interface IFooHelper { ... }
public class FooHelper<T> : IFooHelper where T : struct { ... }

现在在您的Foo-class 中:

public IFooHelper FooHelper
{
    get
    {
        switch (Type)
        {
            case 1:
                return new FooHelper<Guid>("Foo", "Bar", "foobar", "", Guid.NewGuid());
            case 2:
            default:
                return new FooHelper<int>("Bar", "Foo", "", "", 11);
        }
    }
}

但是,如上所述,在编译时无法知道实际的泛型类型参数实际上是什么,因为该类型甚至不存在。

【讨论】:

  • 感谢您的解释。这完全有道理。我想我将不得不解决它,因为接口解决方案也不太可行(例如:无法从接口属性访问泛型类型参数)。
猜你喜欢
  • 1970-01-01
  • 2011-10-08
  • 1970-01-01
  • 1970-01-01
  • 2020-08-06
  • 2019-08-12
  • 2021-12-06
  • 1970-01-01
  • 2011-08-28
相关资源
最近更新 更多