Передать свойство методу в C#

Мне нужно пройти выбор свойств некоторых типов (по одному типу каждый раз), предположим, что это мой тип:

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 может помочь, я думаю, что просто может передать список объектов, но в этом случае я не могу использовать атрибуты и имена, что вы предлагаете для этого? или как то так? если я вообще не прав, то как мне это реализовать?

5 ответов

Вы можете использовать отражение в.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;
   }
}

Забавно, я просто отвечал на подобный вопрос, или, по крайней мере, я так думаю.

Похоже, вы пытаетесь объединить свойства двух типов в один? Вам нужен ExpandoObject:

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

Для реализации вложенного слияния, смотрите это:

C# глубокое / вложенное / рекурсивное слияние динамических / расширяемых объектов

По сути, вы хотите, чтобы список свойств с ключами, начиная с. Следующий код сделает это для любого объекта.NET:

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

И после этого все зависит от того, чего именно вы хотите достичь - точной копии объекта, слияния с другим или просто ведения списка.

Вы можете использовать список PropertyInfo, List<PropertyInfo> как тип вашего TargetType .Properties, Чтобы получить свойства, вы можете попробовать это, используя это Reflection,

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

Вы можете создать список свойств, используя деревья выражений, например, вы можете сделать что-то вроде этого:


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

var target = new TargetType();
target.Properties = propertiesListBuilder.Properties;

Единственное, что здесь беспокоит, это производительность, то есть, может быть, не стоит создавать такие списки свойств снова и снова, скорее всего, их следует кэшировать. В то же время вы получите intellisense, проверки компилятора и поддержку рефакторинга для ваших списков свойств.

Ниже приведен пример реализации этого материала.


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

typeof(Product).GetProperties() даст вам все (публичные) свойства как PropertyInfo[],

Смотрите также MSDN.

Другие вопросы по тегам