C#字符串变量的通用参数

时间:2015-12-14 16:58:07

标签: c# generics reflection attributes

我有两个班级,即客户和国家。客户有一个名为HomeCountry的属性,我用一个名为" Lookup"的自定义属性进行了装饰。并采用字符串参数" Country"。目的是,当我使用Customer类时,HomeCountry中的项必须存在于Country类中(恰好是列表)。

我使用反射迭代Customer类,它找到属性,我希望它检查国家/地区项列表中的值。到目前为止,我有:

foreach (PropertyInfo _pi in object.GetType().GetProperties()) {
  IEnumerable<Attribute> _attrs = _pi.GetCustomAttributes();
  foreach (Attribute _a in _attrs) {
    Object obj = Activator.CreateInstance(_type, null);
    // what goes here?
  }
}

我有一个方法:

public T Populate<T>(params string[] _parameters)

我想我想做

List<obj> v = populate<obj>();

List<typeof(obj)> v = populate<typeof(obj)>();

但显然什么都行不通!有人能帮助我吗?

由于

2 个答案:

答案 0 :(得分:0)

好的我会尝试提供一个完整的例子:

我有一个CUSTOMER_ORDER类:

public class CUSTOMER_ORDER {
  public CUSTOMER_ORDER() {}

  [Key(0)]
  public string OrderNumber {get;set;}
  public MPCCOM_SHIP_VIA ShipVia {get;set;}
}

然后是MPCCOM_SHIP_VIA类:

public class MPCCOM_SHIP_VIA {
  public MPCCOM_SHIP_VIA() {}

  [Key(0)]
  public string ID {get;set;}
  public string Description {get;set;}
}

我有一个名为Populate&lt;的方法T>接受一个类,然后使用反射循环所有属性并构建一个select语句,执行它,然后返回数据并填充对象:

public T Populate<T>(params string[] @Parameters)
        {
            Type _t = typeof(T);
            dynamic _o = Activator.CreateInstance(typeof(T), null);

            SqlBuilder _sb = new SqlBuilder();
            _sb.Table = string.Format("{0}.{1}", _Owner, _t.Name.ToString());
            foreach (PropertyInfo p in _t.GetProperties(Utilities.BindingFlags))
            {
                if (p.GetMethod.IsPrivate == false) _sb.Fields.Add(p.Name.ToString());
                IEnumerable<Attribute> _attrs = p.GetCustomAttributes();
                foreach (Attribute _a in _attrs)
                {
                    if (_a.TypeId.ToString().Equals(typeof(Key).FullName))
                    {
                        int _position = ((Key)_a).Position;
                        try
                        {
                            string _parameter = @Parameters[_position];
                            _sb.Where.Add(string.Format("{0} = '{1}'", p.Name, _parameter));
                        }
                        catch {}
                    }
                }
            }

            using (OleDbCommand _cmd = new OleDbCommand())
            {
                _cmd.Connection = this._cn;
                _cmd.CommandText = _sb.SQL;
                if (_trn != null) _cmd.Transaction = _trn;
                _cmd.CommandType = System.Data.CommandType.Text;
                using (OleDbDataReader _reader = _cmd.ExecuteReader())
                {
                    if (_reader.Read())
                    {
                        for (int x = 0; x < _reader.FieldCount; x++)
                        {
                            foreach (PropertyInfo p in _t.GetProperties(Utilities.BindingFlags))
                            {

                                if (p.GetMethod.IsPrivate == false)
                                {
                                    if (p.Name.Equals(_reader.GetName(x).ToString()))
                                    {
                                        dynamic _val = _reader.GetValue(x);
                                        if (p.ReflectedType.BaseType.Name.Equals(""))
                                        {
                                            // what goes here!

                                        }
                                        try
                                        {
                                            p.GetSetMethod(true).Invoke(_o, new object[] { _val });
                                        }
                                        catch { }
                                        break;
                                    }
                                }
                            }
                        }
                    }
                    else
                    {
                        throw new DatabaseObjectNotFound(_t.Name.ToString(), string.Join(",",@Parameters));
                    }
                }
            }
            return (T)_o;

        }

因此,当我读取订单时,源DB获取相应字段中MPCCOM_SHIP_VIA的密钥,我想使用密钥对MPCCOM_SHIP_VIA对象调用相同的Populate方法。我希望这更能说明我想做什么。谢谢

答案 1 :(得分:0)

经过一番狩猎,这就是我正在寻找的答案......

MethodInfo method = typeof(class).GetMethod("Populate");
method = method.MakeGenericMethod(p.PropertyType);
_val = method.Invoke(class, new object[] { _prms });

我想我的问题是我问的是错误的问题!