如何约束方法返回类型where:Attribute

时间:2014-05-13 05:51:58

标签: c# generics attributes

我有一个属性

[System.AttributeUsage(System.AttributeTargets.Class]
public class ModuleValues : System.Attribute
{
    public Guid? Id { get; set; }

    public ModuleValues(string id)
    {
        Id = Guid.Parse(id);
    }
}

如何创建一旦找到后返回属性的泛型方法?

public static T GetAttribute<T>(Type type) where T : Attribute
{
    object[] attrs = typeof(T).GetCustomAttributes(true);
    foreach (Attribute attr in attrs)
    {
        if (attr.GetType() == typeof (T))
        {
            //Console.WriteLine(attr.ToString());
            return attr as T;
        }
    }

    return default(T);
}

有了约束,我的方法总是返回null。

当我删除约束时,我可以使用Console.WriteLine找到该属性,但无法返回它,因为行return attr as T;给出了编译错误The type parameter 'T' cannot be used with the 'as' operator because it does not have a class type constraint nor a 'class' constraint

我的控制台使用示例:

Assembly x = Assembly.GetAssembly(typeof(MyBase));

Type[] types = x.GetTypes();
foreach (Type type in types)
{
    if (type.IsSubclassOf(typeof (MyBase)))
    {
        ModuleValues s = CustomAttributeHelper.GetAttribute<ModuleValues>(type);
        Console.WriteLine("S" + s);
    }
}

2 个答案:

答案 0 :(得分:2)

这应该是:

object[] attrs = type.GetCustomAttributes(true);

typeof(T)更改为输入typeGetCustomAttributes方法获取被调用类型的属性。

答案 1 :(得分:2)

这一行是问题所在:

object[] attrs = typeof(T).GetCustomAttributes(true);

您在GetCustomAttributes上呼叫Type - 而不是您真正感兴趣的类型。您想要:

object[] attrs = type.GetCustomAttributes(true);

或者更确切地说,用以下方法替换方法的其余部分:

return (T) type.GetCustomAttributes(typeof(T), true).FirstOrDefault();

请注意,这也将获取属于T的子类的属性,但我希望无论如何都会更有用,在极少数情况下,您实际上在属性上使用继承