Bry*_*tts 494 c# generics .net-attributes
这会导致编译时异常:
public sealed class ValidatesAttribute<T> : Attribute
{
}
[Validates<string>]
public static class StringValidation
{
}
Run Code Online (Sandbox Code Playgroud)
我意识到C#不支持通用属性.然而,经过大量的谷歌搜索,我似乎无法找到原因.
有谁知道为什么泛型类型无法衍生出来Attribute?任何理论?
Jon*_*eet 350
好吧,我无法回答为什么它不可用,但我可以确认它不是CLI问题.CLI规范没有提到它(据我所见),如果你直接使用IL,你可以创建一个通用属性.禁止它的C#3规范的一部分 - 第10.1.4节"类基本规范"没有给出任何理由.
带注释的ECMA C#2规范也没有给出任何有用的信息,尽管它确实提供了一个不允许的例子.
我的带注释的C#3规范的副本应该明天到达......我会看看是否会提供更多信息.无论如何,它绝对是一种语言决策,而不是运行时决定.
编辑:Eric Lippert的回答(释义):没有特别的原因,除了避免语言和编译器的复杂性,用于不增加太多价值的用例.
Gee*_*key 20
我不知道为什么不允许,但这是一种可行的解决方法
[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
{
....
}
Run Code Online (Sandbox Code Playgroud)
Hos*_*imi 16
自 C# 11 起通用属性可用。现在,这是可能的:
[GenericAttribute<int>()]
public int Method();
Run Code Online (Sandbox Code Playgroud)
然而,这还不可能:
[GenericAttribute<T>()]
public int Method<T>(T param);
Run Code Online (Sandbox Code Playgroud)
T在编译时是未知的。
还,
类型参数必须满足与 typeof 运算符相同的限制。不允许需要元数据注释的类型。例如,不允许使用以下类型作为类型参数:
dynamicstring?(或任何可为空的引用类型)(int X, int Y)(或使用 C# 元组语法的任何其他元组类型)。这些类型不直接在元数据中表示。它们包括描述类型的注释。在所有情况下,您都可以使用基础类型:
object为了dynamic。string代替string?。ValueTuple<int, int>代替(int X, int Y)。
来源:https ://learn.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-11#generic-attributes
naw*_*fal 13
这不是真正的通用,你仍然需要为每种类型编写特定的属性类,但是你可以使用通用的基本接口来编写一些防御性的代码,编写比其他要求更少的代码,获得多态性等的好处.
//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
{
}
Run Code Online (Sandbox Code Playgroud)
这个问题问得好.在我与属性的经验,我认为约束是在地方,因为一个属性反映时,将创建您必须检查所有可能的排列型的条件:typeof(Validates<string>),typeof(Validates<SomeCustomType>),等...
在我看来,如果根据类型需要自定义验证,属性可能不是最好的方法.
接受a SomeCustomValidationDelegate或ISomeCustomValidator作为参数的验证类可能是更好的方法.
这目前不是 C# 语言功能,但是在官方 C# 语言 repo 上有很多讨论。
来自一些会议笔记:
尽管这在原则上是可行的,但大多数版本的运行时都存在错误,因此无法正常工作(从未执行过)。
我们需要一种机制来了解它在哪个目标运行时上工作。我们在很多事情上都需要它,目前正在研究这一点。在那之前,我们不能接受。
主要 C# 版本的候选者,如果我们可以让足够数量的运行时版本处理它。
| 归档时间: |
|
| 查看次数: |
66222 次 |
| 最近记录: |