我有一个包含很多属性的类,我需要将这个类属性名称发布到web服务。
简单的解决方案就是手动创建该数组,如new[] {"Id", "Name", "Date", "etc"}
中所示。
但这并不好玩,我希望得到智能感知支持。到目前为止,我想出了一个带有所有这些属性的enum
,然后有一个辅助函数,它接受这些枚举的数组并在每个上调用.ToString()并添加到数组。
问题 - 相当无用的枚举,如果我的类得到更新,我需要手动将枚举与类属性同步。
我心目中的理想解决方案是使用LINQ扩展方法,我可以传递属性,类似于Select - ToPropertiesArray(x => {x.Id, X.Name, x.Date})
我只是疯了,这不可能完成而且显然是愚蠢的?或者建议如何通过某种IntelliSense支持传递属性名称?
答案 0 :(得分:1)
public class MyClass
{
public int Id{get;set;}
public string S{get;set;}
public double D{get;set;}
}
public static string[] GetPropsNamesArray<T>(Expression<Func<T,Object>> expr)
{
var t = GetObjectType(expr);
var res = t.GetProperties(BindingFlags.Instance|BindingFlags.Public)
.Select(pi => pi.Name)
.ToArray();
return res;
}
public static Type GetObjectType<T>(Expression<Func<T, object>> expr)
{
if ((expr.Body.NodeType == ExpressionType.Convert) ||
(expr.Body.NodeType == ExpressionType.ConvertChecked))
{
var unary = expr.Body as UnaryExpression;
if (unary != null)
return unary.Operand.Type;
}
return expr.Body.Type;
}
并使用:
var selectedPropsNames = GetPropsNamesArray<MyClass>(m => new {m.Id,m.S});
var allPropsNames = GetPropsNamesArray<MyClass>(m => m);
答案 1 :(得分:0)
正如Lars所说,你可以使用反射。在方法中使用反射也可以让您在属性集合更改时不必重写。下面的示例的开头迭代实体的公共属性。
System.Reflection.PropertyInfo[] properties = entity.GetType().GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance);
foreach (System.Reflection.PropertyInfo propertyInfo in properties)
{
// ...
}
答案 2 :(得分:0)
要获得Intellisense支持,您可以使用表达式:
public static class Helper
{
public static List<string> ToPropertiesArray(params System.Linq.Expressions.Expression<Func<object>>[] exprs)
{
return exprs.Select(expr => ((expr.Body as System.Linq.Expressions.UnaryExpression).Operand
as System.Linq.Expressions.MemberExpression).Member.Name)
.ToList();
}
}
样本用法:
SomeClass cl = new SomeClass();
var types = Helper.ToPropertiesArray(() => cl.SomeField, () => cl.SomeOtherField);