自定义 C# 属性

Pha*_*dra 4 c# asp.net .net-core

创建自定义属性时,会创建一个从 ValidationAttribute 类扩展而来的自定义类。

public class CustomAttribute: ValidationAttribute
    {
        
       public void Test()
        {
             Console.WriteLine("Hello World");
         }
        public override bool IsValid(object? value)
        {
            //Logic here
            if (condition)
            {
                return true;
            }
            else
                return false;

        }

      }
Run Code Online (Sandbox Code Playgroud)

假设此自定义属性放置在模型的属性之上。

[Custom]
 public string username { get; set; }
Run Code Online (Sandbox Code Playgroud)

通过将自定义放置在属性上,我实例化了自定义类。现在我的查询是

  1. 如何以及何时调用 IsValid() 方法?
  2. 为什么不调用 CustomAttribute 类中的其他方法?(在本例中为 Test() 方法)
  3. 特定方法在 CustomAttribute 类中运行的基础是什么?

Dai*_*Dai 5

通过放置[Custom]该属性,我正在实例化该类Custom

不,那是不正确的。

Attribute仅当您使用这些方法时才会创建实例(并调用其构造函数)GetCustomAttributes()。此处讨论:何时运行自定义属性的构造函数?

该方法如何以及何时IsValid()被调用?

仅当某些验证服务(可以是任何东西!)有意选择使用并且它也专门使用来查找ValidationAttribute子类时。GetCustomAttributes() IsValid()

CustomAttribute为什么不调用类中的其他方法?(在本例中为Test()方法)

因为您发布的代码都没有显示任何CustomAttribute通过反射实例化并调用.Test()它们的尝试。

特定方法在CustomAttribute类中运行的基础是什么?

仅当该属性由实例化GetCustomAttributes() 并且消费者(调用程序)专门编写为使用 中的方法时[CustomAttribute]


小智 5

你的理解基础不正确。您假设这里起作用的是Attribute您需要关注代码行为。
属性是“数据”类——它们不会单独起作用。
它们在执行Reflection类和属性时非常有用。
在DLL或EXE中你可以在工作中看到这些数据。属性有助于“标记”某些事物,我建议更多地了解反射。

对于您的问题:

  1. IsValid由框架或者你自己调用,需要Attribute专门提取这些类型并调用IsValid。一个很好的提示是override关键字 - 意味着有其他东西可以管理此行为。
  2. 虽然这是可能的 - 通过反射提取所有公共方法并调用它们,但框架并不是为了调用自定义公共方法而设计的,因为它是不安全的、意外的并且通常不推荐。
  3. 在框架基础上 - 如果框架被设计为调用这些方法,那么它们就会调用它们,否则它根本不会关心您定义的方法。

例如,让我们假设这个愚蠢的属性:

    public class MyAttrib : ValidationAttribute
    {
        public MyAttrib()
        {
            Console.WriteLine("Hello from attrib ctor");

        }
        public override bool IsValid(object? value)
        {
            if (value == null) return false;
            if (value != null && value.GetType() != typeof(string))
            {
                return false;
            }
            string? s = value as string;
            return s == "Hello World";
        }
    }

    [MyAttrib]
    public class A
    {

    }
Run Code Online (Sandbox Code Playgroud)

实施框架需要做这样的事情:

            var assm = Assembly.GetExecutingAssembly();

            foreach (var type in assm.GetTypes())
            {
                if (type.IsAssignableFrom(typeof(A)))
                {
                    Console.WriteLine($"Found type {type}");
                    var attributeType = type.GetCustomAttribute<MyAttrib>();
                    var isValid = attributeType.IsValid("Hello World");
                    Console.WriteLine($"Is Valid? {isValid}");
                }
            }
Run Code Online (Sandbox Code Playgroud)

我更关注反射,因为这是理解属性的关键。


关于 ASP.net 等框架的一些知识:这些框架广泛用于Reflection执行许多任务并将行为“委托”给用户代码。
一个有趣的实验是在您的方法上放置断点override,然后查看它们在代码中的何处被调用。还要检查不同的属性及其拥有的内容,它们的基础是标记某些数据或行为,例如对ValidationAttribute数据执行验证。

祝你好运!