2012-03-20 81 views
14

正如討論的here,C#不支持通用屬性聲明。 所以,我不能做這樣的事情:C#通用屬性限制的解決方法

[Audit<User> (UserAction.Update)] 
public ActionResult SomeMethod(int id){ ... 

,將適合像我的屬性實現類魅力,因爲我需要從一個通用存儲庫調用一個方法:

User fuuObj = (User) repository.LoadById<T>(_id); 

我試圖用this解決方案沒有成功。我可以通過像typeOf(User)這樣的東西,但是我怎樣才能撥打LoadById只需輸入類型或魔術字符串?

* T和User都擴展名爲Entity的基類。

+1

你能寫對每種類型不同的屬性? – 2012-03-20 14:22:50

+0

您是否需要特定的課程或實體才能使用? – Bas 2012-03-20 14:26:07

+0

@丹尼爾,是的......但我實際上更喜歡中心所有的聽覺過程,並避免在這種情況下最大可能的未來代碼。 – Custodio 2012-03-20 14:28:36

回答

16

您可以使用反射通過ID加載:

public class AuditAttribute : Attribute 
{ 
    public AuditAttribute(Type t) 
    { 
     this.Type = t; 
    } 

    public Type Type { get; set; } 

    public void DoSomething() 
    { 
     //type is not Entity 
     if (!typeof(Entity).IsAssignableFrom(Type)) 
      throw new Exception(); 

     int _id; 

     IRepository myRepository = new Repository(); 
     MethodInfo loadByIdMethod = myRepository.GetType().GetMethod("LoadById"); 
     MethodInfo methodWithTypeArgument = loadByIdMethod.MakeGenericMethod(this.Type); 
     Entity myEntity = (Entity)methodWithTypeArgument.Invoke(myRepository, new object[] { _id }); 
    } 
} 
4

你至少有以下三種可能性:

  1. 你可以使用反射來調用LoadById
  2. 您可以創建一個表達式樹調用LoadById
  3. 你可以提供你的儲存庫LoadById方法不是通用的。