代码之家  ›  专栏  ›  技术社区  ›  Tim Hutchison

从泛型对象列表中读取泛型值

  •  2
  • Tim Hutchison  · 技术社区  · 6 年前

    我正在尝试循环遍历泛型对象列表调用 Condition<T> 读取通用字段 Value .我跟踪了 this 问题,以便能够存储 List<Condition<T>> .我现在遇到的问题是我不能使用 价值 我循环中的字段。要使用 价值 领域

    主要的

    string url = "";
    List<ConditionBase> Conditions = new List<ConditionBase>();
    Conditions.Add(new Condition<int>(Field.Field1, 1, ConditionOperator.Equal))
    Conditions.Add(new Condition<string>(Field.Field2, "test", ConditionOperator.NotEqual))
    
    foreach (ConditionBase c in Conditions)
    {
        if (c.GetType() == typeof(string))
        {
            // c.Value throws an error
            url += c.Field + " " + c.ConditionOperator + " '" + c.Value + "' and ";
        }
        else if (c.GetType() == typeof(DateTime))
        {
            // c.Value throws an error
            url += c.Field + " " + c.ConditionOperator + " " + Helpers.FormatDate(c.Value) + " and ";
        }
    }
    

    条件基础

    public interface ConditionBase
    {
        Field Field { get; set; }
        ConditionOperator ConditionOperator { get; set; }
    }
    

    条件

    public class Condition<T> : ConditionBase
    {
        private Field _Field;
        private T _Value;
        private ConditionOperator _ConditionOperator;
    
        public Condition(Field field, T value, ConditionOperator condition)
        {
            this._Field = field;
            this._Value = value;
            this._ConditionOperator = condition;
        }
    
        public Field Field
        {
            get
            {
                return this._Field;
            }
            set
            {
                if (this._Field != value)
                {
                    this._Field = value;
                }
            }
        }
    
        public T Value
        {
            get
            {
                return this._Value;
            }
            set
            {
                if (!EqualityComparer<T>.Default.Equals(this._Value, value))
                {
                    this._Value = value;
                }
            }
        }
    
        public ConditionOperator ConditionOperator
        {
            get
            {
                return this._ConditionOperator;
            }
            set
            {
                if (this._ConditionOperator != value)
                {
                    this._ConditionOperator = value;
                }
            }
        }
    }
    

    枚举类型

    public enum Field{
        Field1,
        Field2
    }
    
    public enum ConditionOperator{
        Equal,
        NotEqual,
        GreaterThan,
        LessThan
    }
    

    解决方案

    此解决方案基于@orhtej2&的评论;答案是@Igor。

    Main-测试

    static void Main(string[] args)
    {
        var x1 = new Condition<int>(new Field(), 123, ConditionOperator.Equal);
        var x2 = new Condition<string>(new Field(), "test", ConditionOperator.Equal);
        var x3 = new Condition<DateTime>(new Field(), new DateTime(2018,5,5), ConditionOperator.Equal);
    
        var qqq = new List<ConditionBase>();
    
        qqq.Add(x1);
        qqq.Add(x2);
        qqq.Add(x3);
    
        foreach (ConditionBase c in qqq)
        {
            Console.WriteLine(c.GetValue());
        }
        Console.ReadLine();
    }
    

    条件基础

    public interface ConditionBase
    {
        Field Field { get; set; }
        ConditionOperator ConditionOperator { get; set; }
        string GetValue();
    }
    

    条件

    public class Condition<T> : ConditionBase
    {
        private Field _Field;
        private T _Value;
        private ConditionOperator _ConditionOperator;
    
        public Condition(Field field, T value, ConditionOperator condition)
        {
            this._Field = field;
            this._Value = value;
            this._ConditionOperator = condition;
        }
    
        public Field Field
        {
            get
            {
                return this._Field;
            }
            set
            {
                if (this._Field != value)
                {
                    this._Field = value;
                }
            }
        }
    
        public T Value
        {
            get
            {
                return this._Value;
            }
            set
            {
                if (!EqualityComparer<T>.Default.Equals(this._Value, value))
                {
                    this._Value = value;
                }
            }
        }
    
        public ConditionOperator ConditionOperator
        {
            get
            {
                return this._ConditionOperator;
            }
            set
            {
                if (this._ConditionOperator != value)
                {
                    this._ConditionOperator = value;
                }
            }
        }
    
        public string GetValue()
        {
            if (Value is string)
            {
                return "'" + Value.ToString() + "'";
            }
            else if (Value is DateTime)
            {
                return Helpers.FormatDate(Convert.ToDateTime(Value));
            }
            else
            {
                return Value.ToString();
            }            
        }
    }
    

    枚举类型

    公共枚举字段{
    字段1,
    字段2
    }
    
    公共枚举条件运算符{
    相同的
    NotEqual,
    比…大,
    莱斯坦
    }
    
    1 回复  |  直到 6 年前
        1
  •  3
  •   Igor    6 年前

    代码中存在语法错误,例如缺少枚举的公共范围,以及 ConditionOperator.Equal (不是 ConditionOperator.Equals )但这里的助理是解决办法。

    1. Conditions 应为类型 List<ConditionBase>
    2. 使用 OfType 在列表中检索并将结果类型强制转换为 Condition<string> 我想这是你的意图 c.GetType() == typeof(string)
    string url = "";
    List<ConditionBase> Conditions = new List<ConditionBase>();
    Conditions.Add(new Condition<int>(Field.Field1, 1, ConditionOperator.Equal));
    Conditions.Add(new Condition<string>(Field.Field2, "test", ConditionOperator.NotEqual));
    
    foreach (var c in Conditions.OfType<Condition<string>>())
    {
        url += c.Field + " " + c.ConditionOperator + " '" + c.Value + "' and ";
    }
    

    如果您想要一个可以在所有实例上访问的泛型属性,而不管泛型类型约束如何,那么您需要相应地扩展基本接口。

    public interface ConditionBase
    {
        Field Field { get; set; }
        ConditionOperator ConditionOperator { get; set; }
        object FieldValue { get; }
    }
    
    public class Condition<T> : ConditionBase
    {
      /* I only included the added code in this type */
      public object FieldValue
      {
          get { return (object) this.Value; }
      }
    }
    
    string url = "";
    List<ConditionBase> Conditions = new List<ConditionBase>();
    Conditions.Add(new Condition<int>(Field.Field1, 1, ConditionOperator.Equal));
    Conditions.Add(new Condition<string>(Field.Field2, "test", ConditionOperator.NotEqual));
    
    foreach (var c in Conditions)
    {
        url += c.Field + " " + c.ConditionOperator + " '" + c.FieldValue + "' and ";
    }
    

    您似乎希望根据问题中的更改将值输出到字符串。向您的类型添加字符串格式化程序。

    /* I only included the added code in this type */
    public class Condition<T> : ConditionBase
    {
      private Func<T, string> _formatValue;
      public Condition(Field field, T value, ConditionOperator condition, Func<T, string> formatValue)
      {
        this._Field = field;
        this._Value = value;
        this._ConditionOperator = condition;
        this._formatValue = formatValue;
      }
    
      public override string ToString()
      {
          return this._formatValue(this.Value);
      }
    }
    
    string url = "";
    List<ConditionBase> Conditions = new List<ConditionBase>();
    Conditions.Add(new Condition<int>(Field.Field1, 1, ConditionOperator.Equal, (val)=> val.ToString()));
    Conditions.Add(new Condition<string>(Field.Field2, "test", ConditionOperator.NotEqual, (val)=> val));
    
    foreach (var c in Conditions)
    {
        url += c.Field + " " + c.ConditionOperator + " '" + c.ToString() + "' and ";
    }