سؤال

I have an attribute

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

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

How can I create a generic method that returns the attribute once found?

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);
}

With the constraint in place, my method always returns null.

When I remove the constraint, I can find the attribute with a Console.WriteLine but cannot return it because the line return attr as T; gives compile error The type parameter 'T' cannot be used with the 'as' operator because it does not have a class type constraint nor a 'class' constraint

Example usage from my console:

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);
    }
}
هل كانت مفيدة؟

المحلول

This line is the problem:

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

You're calling GetCustomAttributes on Type - not on the type that you're actually interested in. You want:

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

Or rather more simply, replace the rest of the method with:

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

Note that that will also pick up attributes which are subclasses of T, but I'd expect that to be more useful anyway, in the rare cases where you're actually using inheritance on attributes.

نصائح أخرى

This should be:

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

Changing typeof(T) to input type. The GetCustomAttributes method gets attributes ON the called type.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top