C# 如何强制开发人员将属性应用于类?
我正在创建一个基类。我希望如果它被某个派生类继承,它必须应用一个属性,否则会抛出编译错误。可能吗C# 如何强制开发人员将属性应用于类?,c#,.net,attributes,C#,.net,Attributes,我正在创建一个基类。我希望如果它被某个派生类继承,它必须应用一个属性,否则会抛出编译错误。可能吗 public class MyAttribte : Attribute { public string TestString {get; set; } } public class Base { } /*Attribute must be applied else throw compile time error.*/ [MyAttribte] public class Derived
public class MyAttribte : Attribute
{
public string TestString {get; set; }
}
public class Base
{
}
/*Attribute must be applied else throw compile time error.*/
[MyAttribte]
public class Derived : Base { }
您不能强制,但若未指定
属性,则可以在运行时检查并抛出异常
var d1 = new Derived1(); // OK
var d2 = new Derived2(); // throw error at run-time
public class Base
{
public Base()
{
CheckCustomAttribute();
}
private void CheckCustomAttribute()
{
if (!(this.GetType() == typeof(Base))) // Ingore Base for attribute
{
// var attr = System.Attribute.GetCustomAttributes(this.GetType()).SingleOrDefault(t=>t.GetType() == typeof(CustomAttribute));
var attr = System.Attribute.GetCustomAttributes(this.GetType()).SingleOrDefault(t => typeof(CustomAttribute).IsAssignableFrom(t.GetType())); // to include derived type of Custom attribute also
if (attr == null)
{
throw new Exception(String.Format("Derived class {0} doesnot apply {1} attribute", this.GetType().Name, typeof(CustomAttribute).Name));
}
}
}
}
[CustomAttribute]
class Derived1 : Base
{
}
class Derived2 : Base
{
}
class CustomAttribute : System.Attribute
{
}
您不能强制,但若未指定属性,则可以在运行时检查并抛出异常
var d1 = new Derived1(); // OK
var d2 = new Derived2(); // throw error at run-time
public class Base
{
public Base()
{
CheckCustomAttribute();
}
private void CheckCustomAttribute()
{
if (!(this.GetType() == typeof(Base))) // Ingore Base for attribute
{
// var attr = System.Attribute.GetCustomAttributes(this.GetType()).SingleOrDefault(t=>t.GetType() == typeof(CustomAttribute));
var attr = System.Attribute.GetCustomAttributes(this.GetType()).SingleOrDefault(t => typeof(CustomAttribute).IsAssignableFrom(t.GetType())); // to include derived type of Custom attribute also
if (attr == null)
{
throw new Exception(String.Format("Derived class {0} doesnot apply {1} attribute", this.GetType().Name, typeof(CustomAttribute).Name));
}
}
}
}
[CustomAttribute]
class Derived1 : Base
{
}
class Derived2 : Base
{
}
class CustomAttribute : System.Attribute
{
}
您可以在编译时使用。编译后使用静态代码编织的框架(也称为后编译过程)提供了验证代码设计的API。我创建了一个简单的示例来演示这一点。
定义你的属性
public class MyAttribute : Attribute
{
}
接下来是类,您要将此属性应用于该类。我将注释掉属性以获取错误
//[MyAttribute]
internal class Program
{
private static void Main(string[] args)
{
Console.WriteLine("Hello World");
}
}
现在将您的特性
装箱。它将检查在编译后的程序中是否存在任何MyAttribute
,如果不存在,则填充一条错误消息
[Serializable]
public class MyValidationAspect : AssemblyLevelAspect
{
public override bool CompileTimeValidate(_Assembly assembly)
{
IEnumerable<object> myAttributes = typeof (Program).GetCustomAttributes(inherit: true)
.Where(atr => atr.GetType() == typeof (MyAttribute));
if (!myAttributes.Any())
Message.Write(MessageLocation.Of(typeof (Program)), SeverityType.Error, "DESIGN1",
"You haven't marked {0} with {1}", typeof (Program), typeof (MyAttribute));
return base.CompileTimeValidate(assembly);
}
}
所以现在,当我尝试构建解决方案时,我会得到一个错误:
PostSharpPlay.exe
是我的控制台程序集的名称。
如果在MyAttribute
之前删除注释,则解决方案将编译,并且不会出现错误
您可以在编译时使用。编译后使用静态代码编织的框架(也称为后编译过程)提供了验证代码设计的API。我创建了一个简单的示例来演示这一点。
定义你的属性
public class MyAttribute : Attribute
{
}
接下来是类,您要将此属性应用于该类。我将注释掉属性以获取错误
//[MyAttribute]
internal class Program
{
private static void Main(string[] args)
{
Console.WriteLine("Hello World");
}
}
现在将您的特性
装箱。它将检查在编译后的程序中是否存在任何MyAttribute
,如果不存在,则填充一条错误消息
[Serializable]
public class MyValidationAspect : AssemblyLevelAspect
{
public override bool CompileTimeValidate(_Assembly assembly)
{
IEnumerable<object> myAttributes = typeof (Program).GetCustomAttributes(inherit: true)
.Where(atr => atr.GetType() == typeof (MyAttribute));
if (!myAttributes.Any())
Message.Write(MessageLocation.Of(typeof (Program)), SeverityType.Error, "DESIGN1",
"You haven't marked {0} with {1}", typeof (Program), typeof (MyAttribute));
return base.CompileTimeValidate(assembly);
}
}
所以现在,当我尝试构建解决方案时,我会得到一个错误:
PostSharpPlay.exe
是我的控制台程序集的名称。
如果在MyAttribute
之前删除注释,则解决方案将编译,并且不会出现错误
在编译时不可能。为什么不改用抽象/接口功能呢?因为框架不支持它:(.@DJ如果你能详细说明你打算如何使用这种行为,你可能会有一些想法,而不是直接尝试使用属性。这是不可能的…但针对特定情况的创造性方法是可能的-即,看到重用过时的属性(作为方法的示例,我不认为它直接适用于你的情况)。在编译时不可能。为什么不使用抽象/接口功能?因为框架不支持它:(.@DJ如果你能详细说明你打算如何使用这种行为,你可能会有一些想法,而不是直接尝试使用属性。这是不可能的…但针对特定情况的创造性方法是可能的-即,看到重用过时的属性(作为方法的示例,我不认为它直接适用于你的情况)@DJ所以你在postsharp没有成功?只是interesting@DJ那么你在postsharp上没有成功?很有趣