我正在编写自定义属性而不是标记接口
public class FooAssignableAttribute : Attribute
{
...
}
[FooAssignable]
public class Foo
{
...
}
我不能像这样编码字典吗?
Dictionary<string, FooAssignable> dictionary;
避免标记界面,我正在尝试使用自定义的attrutes。为什么我不能写上面的代码?
答案 0 :(得分:2)
不,这不起作用。 C#中泛型集合(或其他泛型)的参数类型必须是可声明的类型,而属性仅作为元数据存在。
您不能拥有FooAssignable类型的对象。您可以拥有一个具有FooAssignable属性的对象,但这与将其作为超类型不同。 FooAssignable不是类或接口,也不是有效的类型说明符。 FooAssignableAttribute是,但这是引用属性本身的类型,而不是用该属性标记的项目。
考虑到在Dictionary中,索引器的out类型是您提供的out类型。但是你不能拥有FooAssignable类型的变量 - 你可以拥有一个已经用FooAssignable标记的类型的变量,但是没有一个基类可以满足所有这些类型。由于该类型声明是非法的,因此该词典将具有非法的,不存在的类型作为其索引器的getter的返回类型,以及许多其他地方。 C#类型检查不能通过具有属性存在性检查的通用机制自发替换。
您希望类型系统检查的任何内容都必须是类型系统的一部分。属性评估没有定义类型,因此类型系统不能为您执行此操作;同时,泛型是最直接与类型系统交互的语言的一部分。您必须通过类型系统来执行这样的检查,这确实意味着将FooAssignableAttribute提升为接口(IFooAssignable?)。
答案 1 :(得分:1)
FooAssignableAttribute
是班级的名字。如果要在代码中引用类,则必须使用其名称。
只有当您将用作属性时(例如上面的Attribute
示例)才能使用尾随“[FooAssignable]
”的简写。当您将它用作类时 - 例如,作为变量声明或泛型类型参数 - 您必须使用其类名。
答案 2 :(得分:1)
只需更改您的班级名称(如果可能):
public class FooAssignable : Attribute
{ ... }
答案 3 :(得分:0)
与您自己的风格指南保持一致,或选择任何存在的风格指南。