【问题标题】:Pass Property to the Method in C#将属性传递给 C# 中的方法
【发布时间】:2012-04-18 07:42:05
【问题描述】:

我需要传递某些类型的属性选择(每次一种类型),假设这是我的类型:

public class Product {

    [PrimaryKey]
    public long Id { get; set; }
    [DisplayName("Name")]
    public string Title { get; set; }
    [Foreignkey(Schema = "Products", Table = "MajorCategory", Column = "Id")]
    [DisplayName("MCat")]
    public string MajorCategory { get; set; }
    [Foreignkey(Schema = "Products", Table = "Category", Column = "Id")]
    [DisplayName("Cat")]
    public string Category { get; set; }
    public long CategoryId { get; set; }
    [BoolAsRadio()]
    public bool IsScanAllowed { get; set; }
}

所以我需要一种方法将此类型的属性列表传递给其他类型(目标类型),并使用属性名称和属性,我不需要值,类似于以下伪代码:

List<Property> propertyList = new List<Property>();
propertyList.Add(Product.Id);
PropertyList.Add(Product.Title);
TargetType target = new TargetType();
target.Properties = propertyList;


public class TargetType  {

   public List<Property> Properties { get; set;}

   GetAttributes() {

      foreach(Property item in Properties){

         Console.WriteLine(item.Name)

         //Get Attributes
      }
   }


}

有没有办法像Product.Id 一样通过并使用它的名称和属性?我不确定,但也许PropertyInfo 可以提供帮助,我认为可以传递对象列表,但在这种情况下我不能使用属性和名称,你有什么建议来处理这个问题?或类似的东西?如果我完全错了,我该如何实施呢?

【问题讨论】:

标签: c# c#-4.0 properties propertyinfo


【解决方案1】:

有趣的是,我刚刚回答了一个类似的问题,或者至少我认为是这样。

您似乎正在尝试将两种类型的属性合并为一种?你需要一个 ExpandoObject:

http://msdn.microsoft.com/en-us/library/system.dynamic.expandoobject%28v=vs.100%29.aspx

有关嵌套合并的实现,请参见:

C# deep/nested/recursive merge of dynamic/expando objects

基本上,您需要一个属性的键控列表来开始。以下代码将对任何 .NET 对象执行此操作:

var props = object.GetType().GetProperties().ToDictionary<PropertyInfo, string>(prop => prop.Name);

然后,这取决于您想要实现的具体目标 - 对象的真实副本、与另一个对象合并,或者只是维护列表。

【讨论】:

    【解决方案2】:

    您可以在这里使用 .NET 中的反射:

    List<PropertyInfo> propertyList = new List<PropertyInfo>();
    Type productType = typeof (Product);
    
    propertyList.Add(productType.GetProperty("Id"));
    propertyList.Add(productType.GetProperty("Title"));
    TargetType target = new TargetType();
    target.Properties = propertyList;
    
    public class TargetType  {
    
       public List<PropertyInfo> Properties { get; set;}
    
       List<object> GetAttributes()
       {
           List<object> attributes = new List<object>();
    
           foreach(PropertyInfo item in Properties)
           {
               Console.WriteLine(item.Name);
               attributes.AddRange(item.GetCustomAttributes(true));
           }
    
           return attributes;
       }
    }
    

    【讨论】:

      【解决方案3】:

      您可以使用PropertyInfoList&lt;PropertyInfo&gt; 的列表作为TargetType .Properties 的类型。要获取属性,您可以使用Reflection 进行尝试。

      targetType.Properties = product.GetType().GetProperties().ToList();
      

      【讨论】:

        【解决方案4】:

        您可以使用表达式树构建属性列表,例如你可以做这样的事情:

        var propertiesListBuilder = new PropertiesListBuilder<Product>(); propertiesListBuilder .AddProperty(_ => _.Id) .AddProperty(_ => _.Title); var target = new TargetType(); target.Properties = propertiesListBuilder.Properties;

        这里唯一关心的是性能,即一遍又一遍地重新创建此类属性列表可能不是一个好主意,很可能它们应该被缓存。同时,您将获得对属性列表的智能感知、编译器检查和重构支持。

        下面是这个东西的一个示例实现。

        static class PropertyInfoProvider<T> { public static PropertyInfo GetPropertyInfo<TProperty>(Expression<Func<T, TProperty>> expression) { var memberExpression = (MemberExpression)expression.Body; return (PropertyInfo)memberExpression.Member; } } class PropertiesListBuilder<T> { public IEnumerable<PropertyInfo> Properties { get { return this.properties; } } public PropertiesListBuilder<T> AddProperty<TProperty>( Expression<Func<T, TProperty>> expression) { var info = PropertyInfoProvider<T>.GetPropertyInfo(expression); this.properties.Add(info); return this; } private List<PropertyInfo> properties = new List<PropertyInfo>(); }

        【讨论】:

          【解决方案5】:

          typeof(Product).GetProperties() 会将所有(公共)属性作为PropertyInfo[] 提供给您。

          另见MSDN

          【讨论】:

          • 我认为这与我的问题无关!
          猜你喜欢
          • 1970-01-01
          • 2013-05-18
          • 1970-01-01
          • 1970-01-01
          • 2021-02-05
          • 2011-03-08
          • 1970-01-01
          • 2023-04-03
          • 1970-01-01
          相关资源
          最近更新 更多