C#停止将自定义属性应用于类
我在C#中创建了一个自定义属性:C#停止将自定义属性应用于类,c#,properties,attributes,custom-attributes,C#,Properties,Attributes,Custom Attributes,我在C#中创建了一个自定义属性: [AttributeUsage(AttributeTargets.Property,Inherited=false,AllowMultiple=false)] 公共类ExampleAttribute:属性 { } 我希望这只适用于属性,但更具体地说,是不是类(只是基类型)的属性 例如: 公共类示例POCO { //这些应该很好。。。 [示例] 公共字符串Prop1{get;set;} [示例] 公共bool Prop2{get;set;} [示例] 公共int
[AttributeUsage(AttributeTargets.Property,Inherited=false,AllowMultiple=false)]
公共类ExampleAttribute:属性
{
}
我希望这只适用于属性,但更具体地说,是不是类(只是基类型)的属性
例如:
公共类示例POCO
{
//这些应该很好。。。
[示例]
公共字符串Prop1{get;set;}
[示例]
公共bool Prop2{get;set;}
[示例]
公共int Prop3{get;set;}
//但这是不允许的,因为它是类,而不是基类型
[示例]
公共OtherExample Prop4{get;set;}
}
公共类示例
{
公共字符串Other1{get;set;}
}
有人知道我如何在编译时进一步限制这个自定义属性吗?如果这只能在运行时完成,那么最好的方法是什么
提前谢谢 在编译时使用直接C#强制执行的数量是有限制的。正如评论中指出的,您可以编写一个自定义Roslyn扩展来查找无效用法。这是一个相当繁重的解决方案——大多数人倾向于在运行时实现这类事情的验证,而不是在编译时 想到的一些例子是Newtonsoft的
JsonConverter
属性,它要求构造函数中的类型实现一个特定的接口,或者Asp.Net的Route
属性,它对语法和歧义有约束。这些东西可以作为Roslyn扩展实现,但最常见的约定是在运行时进行验证
即时验证是您声明所有需要验证的类型(或约定)并立即完成验证的地方。为此声明类型的一些方法包括:
- 将
s的显式列表传递给类型
方法验证
- 创建一个接口,传入一个程序集,并扫描程序集以查找实现该接口的类型
- 生成一个属性,传入一个程序集,并扫描该程序集以查找用它注释的类型
private static readonly Type[] PrimitiveTypes = new Type[]
{
typeof(string),
typeof(int),
typeof(bool),
typeof(int?), // Are nullable primitive types allowed? You decide
}
public static void Validate(Type type)
{
var properties = type.GetProperties();
foreach (var property in properties)
{
var attribute = property.GetCustomAttribute<ExampleAttribute>();
if (attribute == null)
continue;
if (!Array.Contains(PrimitiveTypes, property.PropertyType))
throw new Exception("Make a custom exception type and message for this scenario");
}
}
private静态只读类型[]基元类型=新类型[]
{
类型(字符串),
类型(int),
类型(bool),
typeof(int?,//是否允许使用可为空的基元类型?由您决定
}
公共静态无效验证(类型)
{
var properties=type.GetProperties();
foreach(属性中的var属性)
{
var attribute=property.GetCustomAttribute();
if(属性==null)
继续;
如果(!Array.Contains(PrimitiveTypes,property.PropertyType))
抛出新异常(“为此场景创建自定义异常类型和消息”);
}
}
在本例中,为了简单起见,如果验证失败,我将抛出一个异常。如果您创建一个验证错误列表并返回这些错误,那么它将有助于调试,这样用户就可以看到所有的错误,而不仅仅是第一个错误。您无法在编译时阻止这种情况发生。您在运行时如何处理这种情况?请参阅。