Is there a way to enforce that a type parameter passed to an attribute implement specific interface?
public interface IExpectedInterface
{
    void InterfaceMethod();
}
public class MyCustomAttribute : Attribute
{
    public MyCustomAttribute(Type classType)
    {
        this.ConfirmAssignedClassType();
        _classType = classType;
    }
    public void SomeMethod<T>() where T : IExpectedInterface, new()
    {
        //var expectedType = Activator.CreateInstance(this._classType) as IExpectedInterface;
        var expectedType = Activator.CreateInstance(typeof(T)) as IExpectedInterface;
        if (expectedType == null)
        {
            // Wrong type
            throw new ArgumentException(string.Format("Wrong type: {0} could not be created or converted to IActionAuthorization", _classType.ToString()));
        }
        // Do something with expectedType
        expectedType.InterfaceMethod();
    }
    private void ConfirmAssignedClassType()
    {
        if (!typeof(IExpectedInterface).IsAssignableFrom(_classType))
        {
            // Wrong type
            // Can we enforce it via language construct
            throw new ArgumentException(string.Format("Wrong type: {0} must implement IExpectedInterface", _classType.ToString()));
        }
        if (this._classType.GetConstructor(Type.EmptyTypes) == null)
        {
            // Wrong type
            // Can we enforce it via language construct
            throw new ArgumentException(string.Format("Wrong type: {0} must have parameter less constructor", _classType.ToString()));
        }
    }
    private Type _classType;
}
public class TestClass
{
    [MyCustom(typeof(TestClassImplementsExpectedInterface))]
    public void TestMethod1()
    {
    }
    [MyCustom(typeof(TestClassDoesntImplementExpectedInterface))]
    public void TestMethod2()
    {
    }
}
public class TestClassImplementsExpectedInterface : IExpectedInterface
{
    public void InterfaceMethod()
    {
        return;
    }
}
public class TestClassDoesntImplementExpectedInterface
{
}
                An attribute is a variable of any type that is declared directly in a class. A parameter is a variable defined by the function that receives a value when it is called. An attribute is used with classes and objects. A parameter is used with a function or a method.
The positional parameters for an attribute correspond to the parameters passed to the attribute type's public constructors. The named parameters for an attribute correspond to the set of public read-write or write-only instance properties and fields of the attribute type.
In C#, attributes are classes that inherit from the Attribute base class. Any class that inherits from Attribute can be used as a sort of "tag" on other pieces of code. For instance, there is an attribute called ObsoleteAttribute . This is used to signal that code is obsolete and shouldn't be used anymore.
Attributes provide a powerful method of associating metadata, or declarative information, with code (assemblies, types, methods, properties, and so forth). After an attribute is associated with a program entity, the attribute can be queried at run time by using a technique called reflection.
Couldn't this be done with generics? (Edited -- cannot create a generic subclass of Attribute)
   public class MyAttribute: Attribute 
    {
        private Type _ClassType;
        public MyAttribute(Type classType)
        {
            _ClassType = classType;
        }
        public void SomeMethod<T>() where T: IMyInterface
        {
            var expectedType = Activator.CreateInstance(typeof(T)) as IMyInterface;
        // Do something with expectedType
        }
    }
And of course the other answer's translation to use "new" makes a lot of sense!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With