0

I created an EvaluateAttribute, and I want it to accept various IEvaluators specified like this:

[Evaluate(CatEvaluator, DogEvaluator)]
public void someMethod()
{
}

Since CatEvaluator and DogEvaluator are types, I set up my attribute class like this:

   public class EvaluateAttribute<T> : Attribute where T:IAccessEvaluator

and constructor:

public EvaluateAttribute(params T [] accessEvaluators)
{
    _accessEvaluators = accessEvaluators;
}

C# doesn't like generics and attributes though, it would seem. Is there a solution to this?

I want my attribute to instantiate each type with CreateInstance and run an evaluate method specific in IAccessEvaluator.

NibblyPig
  • 51,118
  • 72
  • 200
  • 356

2 Answers2

1

You probably don't need to use generics if you just want to pass classes implementing IAccessEvaluator. Just change the signature to

public EvaluateAttribute(params IAccessEvaluator [] accessEvaluators)
{
    _accessEvaluators = accessEvaluators;
}

Reread your question. You're using types like objects, so my first impression was to write the above answer. If you need to annotate types, you should have a look at the comment on your question (by MUG4N).

public EvaluateAttribute(params Type [] accessEvaluators)
{
    _accessEvaluators = accessEvaluators;
}

[Evaluate(typeof(CatEvaluator), typeof(DogEvaluator)]
public SomeClass{ }

and change _accessEvaluators to Type[]

Matten
  • 17,365
  • 2
  • 42
  • 64
1

There is nothing to stop the attribute accepting types:

public class EvaluateAttribute : Attribute
{
    private readonly Type[] _accessEvaluators;

    public EvaluateAttribute(params Type[] accessEvaluators)
    {
        _accessEvaluators = accessEvaluators;
    }
}

which you can then use like this:

[Evaluate(typeof(CatEvaluator), typeof(DogEvaluator)]
public void someMethod()
{

}

Unfortunately, you lose the type safety - but you could always add some run-time checking to the attribute's constructor. Something along the lines of:

public EvaluateAttribute(params Type[] accessEvaluators)
{
    foreach (var type in accessEvaluators)
    {
        if (!typeof(IAccessEvaluator).IsAssignableFrom(type))
        {
            throw new InvalidOperationException("Suppied type must be of type IAccessEvaluator");
        }
    }
    _accessEvaluators = accessEvaluators;
}
Rob Levine
  • 40,328
  • 13
  • 85
  • 111