Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/288.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何强制开发人员将属性应用于类?_C#_.net_Attributes - Fatal编程技术网

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上没有成功?很有趣