我很确定这是可能的,但由于某种原因,我似乎无法解决这个问题...我正在尝试从Type中创建一个扩展方法,这会将一个Func接收到一个属性从该类型中,从DefaultValueAttribute中提取DefaultValue。
我可以使它工作,但前提是我为GetDefaultValue函数调用指定了类型参数。这是我目前的代码:
人物实体:
public class Person
{
public string FirstName { get; set; }
[DefaultValue("1234")]
public string DOB { get; set; }
}
调用方法:
//Messing around in LinqPad - .Dump() is LinqPad method
//Works
//typeof(Person).GetDefaultValue<Person, string>(x=>x.DOB).Dump();
//Trying to get to work
//Can't figure out how to get it to infer that TIn is of the Type type.....
typeof(Person).GetDefaultValue(x=> x.DOB).Dump();
这是方法调用的目的...我只是想在我合并到我的实际程序之前弄清楚现在的方法...错误检查将在我弄清楚如何发挥作用要做到这一点,或放弃b / c就无法做到......
public static class Extensions
{
// Works
// public static TProperty GetDefaultValue<TModel, TProperty>(this Type type, Expression<Func<TModel, TProperty>> exp)
// {
// var property = typeof(TModel).GetProperties().ToList().Single(p => p.Name == GetFullPropertyName(exp));
// var defaultValue = (DefaultValueAttribute)property.GetCustomAttributes(typeof(DefaultValueAttribute), false).FirstOrDefault();
// return (TProperty)defaultValue.Value;
// }
//trying to get to work
//I know that I can't do the following, but it is basically what I am trying to do... I think!
public static TProperty GetDefaultValue<TProperty>(this Type type, Expression<Func<typeof(type), TProperty>> exp)
{
var property = type.GetProperties().ToList().Single(p => p.Name == GetFullPropertyName(exp));
var defaultValue = (DefaultValueAttribute)property.GetCustomAttributes(typeof(DefaultValueAttribute), false).FirstOrDefault();
return (TProperty)defaultValue.Value;
}
//GetFullPropertyName c/o: http://stackoverflow.com/users/105570/
//ref: http://stackoverflow.com/questions/2789504/
public static string GetFullPropertyName<TModel, TProperty>(Expression<Func<TModel, TProperty>> exp)
{
MemberExpression memberExp;
if (!TryFindMemberExpression(exp.Body, out memberExp))
return String.Empty;
var memberNames = new Stack<string>();
do
memberNames.Push(memberExp.Member.Name);
while (TryFindMemberExpression(memberExp.Expression, out memberExp));
return String.Join(".", memberNames.ToArray());
}
private static bool TryFindMemberExpression(Expression exp, out MemberExpression memberExp)
{
memberExp = exp as MemberExpression;
if (memberExp != null)
return true;
if (IsConversion(exp) && exp is UnaryExpression)
{
memberExp = ((UnaryExpression)exp).Operand as MemberExpression;
if (memberExp != null)
return true;
}
return false;
}
private static bool IsConversion(Expression exp)
{
return exp.NodeType == ExpressionType.Convert || exp.NodeType == ExpressionType.ConvertChecked;
}
}
我疯了,还是这有可能?提前感谢您的帮助!
答案 0 :(得分:2)
这不是它的工作方式 - typeof(Person)
没有名为DOB
的属性,而是类型为Person的类。你想要的是使你的扩展方法通用:
public static TValue GetDefaultValue<TClass, TValue>(this TClass val, Expression<Func<TClass, TValue>> getter) {
var type = typeof(TClass);
var property = type.GetProperties().ToList().Single(p => p.Name == GetFullPropertyName(exp));
var defaultValue = (DefaultValueAttribute)property.GetCustomAttributes(typeof(DefaultValueAttribute), false).FirstOrDefault();
return (TProperty)defaultValue.Value;
}
并称之为:
Person somePerson = GetMeAPerson();
somePerson.GetDefaultValue(p=>p.DOB);
请注意,我还没有对上面的内容进行过测试,但我在过去看过类似的代码。也就是说,我怀疑你最初尝试做的事情并不是很吸引人,因为你需要先创建一个Person实例。
另一种可能更具吸引力的方法是根本不使它成为一种扩展方法:
public static TValue GetDefaultValue<TClass, TValue>(Expression<Func<TClass, TValue>> getter) {
var type = typeof(TClass);
var property = type.GetProperties().ToList().Single(p => p.Name == GetFullPropertyName(exp));
var defaultValue = (DefaultValueAttribute)property.GetCustomAttributes(typeof(DefaultValueAttribute), false).FirstOrDefault();
return (TProperty)defaultValue.Value;
}
然后你可以在没有实例的情况下调用它,但推理不是很好):
var defaultValue = GetDefaultValue<Person, DateTime>(p => p.DOB);