2012-03-20 83 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方法不是通用的。