1

我正在创建一个基类。我希望如果它被某个派生类继承,它必须应用一个属性,否则会引发编译错误。可能吗?

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 { }
4

2 回答 2

3

您不能强制,但如果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
{
}
于 2013-01-11T06:18:33.473 回答
1

您可以使用PostSharp在编译时执行此操作。AOP框架在编译后使用静态代码编织(也称为编译后过程),提供用于验证您的代码设计的 API。我创建了一个简单的例子来证明这一点。定义你的属性

public class MyAttribute : Attribute
{

}

接下来是要应用此属性的类。我将注释掉属性以获取错误。

//[MyAttribute]
internal class Program
{
    private static void Main(string[] args)
    {
        Console.WriteLine("Hello World");
    }
}

现在装箱你的Aspect. 它将在编译后检查是否MyAttribute存在任何内容Program,如果不存在 - 填充错误消息。

[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);
    }
}

然后在装配级别定义这个方面,如下所示:

[assembly: MyValidationAspect]

所以现在,当我尝试构建解决方案时,我会收到一个错误:

在此处输入图像描述

PostSharpPlay.exe是我的控制台程序集的名称。如果我之前删除评论MyAttribute- 解决方案编译并且我没有收到任何错误。

在此处输入图像描述

于 2013-01-11T11:14:48.967 回答