属性参数的强制类型

| 有没有一种方法可以强制将传递给属性的类型参数实现特定的接口?
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
{
}
    
已邀请:
        不能使用泛型吗? (已编辑-无法创建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
        }
    }
当然,另一个答案的翻译使用“ new”很有意义!     
        如果由于某种原因您不想弄混泛型(例如将所有属性放入列表等),则可以使用一种稍微更好的方法,尽管仍然没有进行编译时检查。您可以调用Type.IsAssignableFrom方法,而不是调用Activator.CreateInstance(根据是否有0参数变量,它可能会起作用,也可能不会起作用)(尽管您似乎假设存在0参数变量,所以这可能有点无聊)。
if (!typeof(SomeInterface).IsAssignableFrom(_ClassType)))
// Throw exception
    
        您可以将方法转换为通用方法,例如
public class MyAttribute : Attribute
{
    public void SomeMethod<T>() where T : ISomeInterface, new()
    {
        var expectedType = new T();
        // Do something with expectedType
    }
}
new()
类型约束表示该类型必须具有公共的无参数构造函数,这意味着您可以执行
new T()
。这样就无需使用
Activator
。 请注意,正如Duncan Howe指出的那样,泛型类型不能从generic7ѭ继承,所以您不能做
public class MyAttribute<T> : Attribute
    
        为什么不仅仅通过构造函数(例如
Public MyAttribute(IMyInterface myObject)
)传递对象并将其存储在属性中。然后,如果需要该类型,则显式调用
typeof(myObjectProperty)
。     

要回复问题请先登录注册