2012-04-09 47 views
1

我想創建一個委託與表達式來讀取自定義屬性。示例代碼是使用MethodCall表達式來調用Attribute.GetCustomAttributes

[AttributeUsage(AttributeTargets.Class)] 
public class TestAttribute : Attribute 
{ 
    public string Description { get; set; } 
} 


[TestAttribute(Description="sample text")] 
public class TestClass 
{ 
} 

我想要獲取描述屬性值與Func委託。我想與在runtime.So創建此代表我試着寫類似

public Func<T, string> CreateDelegate<T>() 
    { 
     //Below is the code which i want to write using expressions 
     //TestAttribute attribute = typeof(T).GetCustomAttributes(typeof(TestAttribute), false)[0]; 
     //return attribute.Description; 

     ParameterExpression clazz = Expression.Parameter(typeof(T),"clazz"); 
     ParameterExpression description = Expression.Variable(typeof(string),"description"); 
     ParameterExpression attribute=Expression.Variable(typeof(TestAttribute),"attribute"); 

     MethodCallExpression getAttributesMethod = Expression.Call(typeof(Attribute).GetMethod("GetCustomAttributes"),clazz); 

     Expression testAttribute = Expression.TypeAs(Expression.ArrayIndex(getAttributesMethod, Expression.Constant(0)), typeof(TestAttribute)); 
     BinaryExpression result = Expression.Assign(description, Expression.Property(testAttribute, "Description")); 

     BlockExpression body = Expression.Block(new ParameterExpression[] { clazz, attribute,description }, 
      getAttributesMethod, testAttribute, result);    

     Func<T, string> lambda = Expression.Lambda<Func<T, string>>(body, clazz).Compile(); 
     return lambda; 
    } 

但是,當我把這種方法,我在getAttributesMethod線得到AmbiguousMatchException和它說「不明確的找到匹配表達式來實現這一目標。 「那麼如何在表達式樹中使用Attribute.GetCustomAttribute()方法?

回答

0

試試這個:

MethodCallExpression getAttributesMethod = Expression.Call(typeof(Attribute), 
    "GetCustomAttributes", null, Expression.Constant(typeof(T))); 

但是,爲什麼你返回Func<T, string>?你在委託調用中用什麼參數?

+0

這是一個使用反射集中的實際方法的簡化版本。我在這裏返回一個代表來擺脫基於反射的缺點。我經常使用一些具有自定義屬性的助手類作爲委託調用中的參數。隨着您的更改上面的代碼工作得很好。感謝您的時間。 – 2012-04-09 18:35:25

0

它實際上是在這裏思考的塊:

typeof(Attribute).GetMethod("GetCustomAttributes") 

GetMethod將拋出該異常,如果有它的過載和你沒有指定的參數類型。

嘗試:

typeof(Attribute).GetMethod("GetCustomAttributes", new [] {typeof(MemberInfo)}) 
+0

此時異常更改爲ArgumentException。 Pufff我堅持住了。 – 2012-04-09 12:57:18

+0

@OlcaySeker你可以在你的問題中替換'blah blah',以便我可以運行代碼嗎? – vcsjones 2012-04-09 12:59:19

+0

確定更改爲更清晰。 – 2012-04-09 13:12:13