為什麼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>)
等...
在我看來,如果根據類型需要自定義驗證,那麼屬性可能不是最好的方法。
也許一個接受SomeCustomValidationDelegate
或ISomeCustomValidator
作為參數的驗證類將是更好的方法。