Передать свойство методу в 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.