Generic list of generic objects

后端 未结 3 1318
醉梦人生
醉梦人生 2020-12-01 12:06

Let\'s say I have an object that represents a field of data, that object needs the following properties: Name, Type, Value, Length. Here is the object:

class         


        
相关标签:
3条回答
  • 2020-12-01 12:53

    I suggest you to define an interface and Field<T> implements that interface

    public interface IField
    {
    
    }
    
    public class Field<T> : IField
    {
        public string Name { get; set; }
        public Type Type
        {
            get
            {
                return typeof(T);
            }
        }
        public int Length { get; set; }
        public T Value { get; set; }
    }
    

    so you can write this code:

    var list = new List<IField>();
    

    now this list can contain any object of type Field<T>

    0 讨论(0)
  • 2020-12-01 12:54

    Yes, generics is a good choice. The key to achieving type-safety (and being identify the type with the Type property is to add an abstraction between the list and Field<T> class.

    Have Field<T> implement the interface IField. This interface doesn't need any members.

    Then declare your list as being List<IField>.

    That way you constrain the list to only contain fields, but each field can be of a different type.

    To then read the values later, just do

    foreach(var field in list)
    {
        var type = field.Type;
        ....
    }
    
    0 讨论(0)
  • 2020-12-01 12:55

    As a few commenters already mentioned, you cannot access the Type property if you create an empty Interface, so I would rather do:

    public interface IField
    {
        Type Type { get; }
    
        string Name { get; set; }
    
        int Length { get; set; }
    }
    
    public class Field<T> : IField
    {
        public string Name { get; set; }
    
        Type IField.Type => typeof(T);
    
        public int Length { get; set; }
    
        public T Value { get; set; }
    
        public override string ToString()
        {
            return Value.ToString();
        }
    }
    

    Then you can check of which datatype the value property is and cast the object to the right type:

    class Program
    {
        static void Main(string[] args)
        {
            var fieldList = new List<IField>()
            {
                new Field<string>()
                {
                    Value = "Hello World!", 
                    Length = 12, 
                    Name = "A string"
                },
                new Field<int>()
                {
                    Value = 4711,
                    Length = sizeof(int),
                    Name = "An integer value"
                },
                new Field<double>()
                {
                    Value = 2.4,
                    Length = sizeof(double),
                    Name = "A double value"
                },
            };
    
            foreach (var field in fieldList)
            {
                if (field.Type == typeof(string))
                {
                    PrintField(field, "String value:");
                }
                else if (field.Type == typeof(int))
                {
                    PrintField(field, "Integer value:");
                }
                else if (field.Type == typeof(double))
                {
                    PrintField(field, "Double value:");
                }
            }
        }
    
        static void PrintField(IField field, string info)
        {
            Debug.WriteLine(info);
            Debug.WriteLine($"\tName: {field.Name}, Length: {field.Length}, Value: {field}");
        }
    }
    

    The code produces the following output:

    // String value:
    //  Name: A string, Length: 12, Value: Hello World!
    // Integer value:
    //     Name: An integer value, Length: 4, Value: 4711
    // Double value:
    //     Name: A double value, Length: 8, Value: 2,4
    
    0 讨论(0)
提交回复
热议问题