為什麼C#禁止泛型屬性類型?




generics .net-attributes (4)

一個屬性在編譯時裝飾一個類,但是泛型類直到運行時才會收到它的最終類型信息。 由於該屬性會影響編譯,因此編譯時必須“完整”。

有關更多信息,請參閱此MSDN文章

這會導致編譯時異常:

public sealed class ValidatesAttribute<T> : Attribute
{

}

[Validates<string>]
public static class StringValidation
{

}

我意識到C#不支持通用屬性。 但是,經過Google搜索之後,我似乎無法找到原因。

有誰知道為什麼泛型類型不能從Attribute派生? 任何理論?


我不知道為什麼它不被允許,但這是一種可能的解決方法

[AttributeUsage(AttributeTargets.Class)]
public class ClassDescriptionAttribute : Attribute
{
    public ClassDescriptionAttribute(Type KeyDataType)
    {
        _KeyDataType = KeyDataType;
    }

    public Type KeyDataType
    {
        get { return _KeyDataType; }
    }
    private Type _KeyDataType;
}


[ClassDescriptionAttribute(typeof(string))]
class Program
{
    ....
}

這不是真正的泛型,你仍然需要為每種類型編寫特定的屬性類,但是你可以使用通用的基本接口來進行防禦性編碼,編寫比其他方式所需的代碼更少的代碼,從而獲得多態性等優點。

//an interface which means it can't have its own implementation. 
//You might need to use extension methods on this interface for that.
public interface ValidatesAttribute<T>
{
    T Value { get; } //or whatever that is
    bool IsValid { get; } //etc
}

public class ValidatesStringAttribute : Attribute, ValidatesAttribute<string>
{
    //...
}
public class ValidatesIntAttribute : Attribute, ValidatesAttribute<int>
{
    //...
}

[ValidatesString]
public static class StringValidation
{

}
[ValidatesInt]
public static class IntValidation
{

}

這個問題問得好。 根據我對屬性的經驗,我認為約束是有原因的,因為當反映一個屬性時,它會創建一個條件,你必須檢查所有可能的類型排列: typeof(Validates<string>)typeof(Validates<SomeCustomType>)等...

在我看來,如果根據類型需要自定義驗證,那麼屬性可能不是最好的方法。

也許一個接受SomeCustomValidationDelegateISomeCustomValidator作為參數的驗證類將是更好的方法。





.net-attributes