C#通用属性限制的解决方法

时间:2012-03-20 14:19:51

标签: c# generics reflection

正如here所讨论的,C#不支持通用属性声明。 所以,我不允许做类似的事情:

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

这就像我的属性impl类中的魅力一样,因为我需要从通用存储库调用一个方法:

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

我尝试使用this解决方案但没有成功。我可以传递类似typeOf(User)的内容,但如何使用类型或魔术字符串调用LoadById

* T和User都扩展了一个名为Entity的基类。

3 个答案:

答案 0 :(得分:17)

你可以使用反射来加载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 });
    }
}

答案 1 :(得分:4)

你至少有这三种可能性:

  1. 您可以使用反射来调用LoadById
  2. 您可以创建一个调用LoadById
  3. 的表达式树
  4. 您可以在存储库中提供非常规的LoadById方法。

答案 2 :(得分:1)

您可以使用反射来调用LoadById方法。以下msdn文章应指出正确的方向:

http://msdn.microsoft.com/en-us/library/b8ytshk6(v=vs.100).aspx