如何声明包含泛型类型的数组?

时间:2016-10-21 15:02:26

标签: c# generics

说我有以下类型:

public class Field<T>
{
  public string Name { get; set; }
  public T Value { get; set; }
}

如何声明包含此类字段数组的变量?我尝试了以下方法:

var customFields = new Field[]
{
    new Field<string> { Name = "nickname", Value = "Bob" },
    new Field<int> { Name = "age", Value = 42 },
    new Field<DateTime> { Name = "customer_since", Value = new DateTime(2000, 12, 1) }
};

但我得到以下编译时异常:

  

使用泛型类型&#39;字段&#39;需要1个类型参数

我也试过了var customFields = new Field<object>[],但我收到了以下错误:

  

无法隐式转换类型&#39;字段&#39;到&#39; Field&#39;

     

无法隐式转换类型&#39;字段&#39;到&#39; Field&#39;

     

无法隐式转换类型&#39;字段&#39;到&#39; Field&#39;

2 个答案:

答案 0 :(得分:14)

正如Matias所说,不能这样做,因为Field<int>Field<string>是完全不同的类型。你能做的是:

创建一个非通用的基础Field

public class Field
{
    public string Name { get; set; }
}

public class Field<T> : Field
{
    public T Value { get; set; }
}

然后:

var customFields = new Field[]
{
    new Field<string> { Name = "nickname", Value = "Bob" },
    new Field<int> { Name = "age", Value = 42 },
    new Field<DateTime> { Name = "customer_since", Value = new DateTime(2000, 12, 1) }
};

正如Matias评论的那样,需要一个向下转换来获得不同类型的Value。如果对于每种不同类型的Value都有一个特定的逻辑要执行,处理它的一个好方法是使用Factory设计模式。工厂将为每个Field返回一个正确的&#34; FieldHandler<T>&#34;这将是垂头丧气,做手术并返回所需的东西。

答案 1 :(得分:2)

您可以做的另一件事是简单地为所有这些类型使用公共基类 - 对象。

class Field
{
    public string Name { get; set; }
    public Object Value { get; set; }
}
var customFields = new Field[]
{
    new Field { Name = "nickname ", Value = "Bob" },
    new Field { Name = "age", Value = 42 },
    new Field { Name = "customer_since", Value = new DateTime(2000, 12, 1) }
};

但是,这会将某些类型处理卸载到customFields的使用者,但如果与特定字段名称关联的Value类型已知,则应该没问题。