简体   繁体   中英

How to declare an array containing generic type?

Say I have the following type:

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

How can I declare a variable that will contain an array of such Fields? I tried the following:

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) }
};

but I get the following compile-time exception:

Using the generic type 'Field' requires 1 type arguments

I also tried var customFields = new Field<object>[] but I get the following errors:

Cannot implicitly convert type 'Field' to 'Field'

Cannot implicitly convert type 'Field' to 'Field'

Cannot implicitly convert type 'Field' to 'Field'

As Matias said it can't be done that way because Field<int> and Field<string> are completely different types. What you can do is:

Create a base Field which is not generic:

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

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

And then:

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) }
};

As Matias commented a downcasting will be needed to get the Value of the different types. If for each different type of Value there is a specific logic to perform, a nice way to handle it will be to use the Factory design pattern. The factory will return for each Field a correct " FieldHandler<T> " that will downcast, do the operation and return what is needed.

Another thing you can do is to simply use the common base class for all of those types - Object.

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) }
};

However, this would be offloading some type handling to the consumer of customFields, but should be fine if the Value types associated with a specific Field Name are known.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM