Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/296.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#_Attributes - Fatal编程技术网

C# 属性类是如何工作的?

C# 属性类是如何工作的?,c#,attributes,C#,Attributes,我的搜索结果只显示了说明如何使用属性和将属性应用于类的指南。我想学习如何创建自己的属性类以及它们如何工作的机制 属性类是如何实例化的?当应用它们的类被实例化时,它们是否被实例化?是否为应用它的每个实例化类实例化一个?例如,如果我将SerializableAttribute类应用于MyData类,并实例化了5个MyData实例,那么会有5个SerializableAttribute类实例在幕后创建吗?或者它们之间只共享一个实例 属性类实例如何访问与其关联的类?SerializableAttribu

我的搜索结果只显示了说明如何使用属性和将属性应用于类的指南。我想学习如何创建自己的属性类以及它们如何工作的机制

属性类是如何实例化的?当应用它们的类被实例化时,它们是否被实例化?是否为应用它的每个实例化类实例化一个?例如,如果我将SerializableAttribute类应用于MyData类,并实例化了5个MyData实例,那么会有5个SerializableAttribute类实例在幕后创建吗?或者它们之间只共享一个实例


属性类实例如何访问与其关联的类?SerializableAttribute类如何访问其应用的类,以便序列化其数据?它是否具有某种序列化属性。这是StanceIAmAppliedTo属性吗?:)或者它的工作方向是相反的,即每当我序列化某个东西时,我传递MyClass实例给的serialize函数都会反射地遍历属性并找到SerialiableAttribute实例?

是的,它们是用您给它的参数实例化的

该属性不“访问”该类。该属性附加到反射数据中类“/属性”的属性列表

[Serializable]
public class MyFancyClass
{ ... }

// Somewhere Else:

public void function()
{
   Type t = typeof(MyFancyClass);
   var attributes = t.GetCustomAttributes(true);

   if (attributes.Count(p => p is SerializableAttribute) > 0)
   {
       // This class is serializable, let's do something with it!

   }     
}

没有太多时间给你一个更完整的答案,但是你可以通过反射找到已经应用到某个值的属性。至于创建它们,您从属性类继承并从那里开始工作,并且您为属性提供的值被传递给属性类的构造函数

已经有一段时间了,你可能知道


Martin

属性本质上是元数据,可以附加到代码的各个部分。这些元数据可以进行互操作,并影响某些操作的行为

属性几乎可以应用于代码的每个方面。例如,可以在程序集级别关联属性,如AssemblyVersion和AssemblyFileVersion属性,它们控制与程序集关联的版本号

[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
然后,可以将Serializable属性(例如)应用于类型声明,以将该类型标记为支持序列化。事实上,该属性在CLR中具有特殊意义,并且实际上作为一个特殊指令直接存储在IL中的类型上,该属性被优化为存储为一个位标志,可以更有效地处理该位标志,在这种性质上有一些属性,称为伪自定义属性

还有其他属性可以应用于方法、属性、字段、枚举、返回值等。通过查看此链接,您可以了解属性可以应用于哪些可能的目标

除此之外,您还可以定义自己的自定义属性,然后将这些属性应用于属性所针对的适用目标。然后在运行时,您的代码可以反映自定义属性中包含的值,并采取适当的操作

举一个相当幼稚的例子,这只是为了举例:) 您可能希望编写一个持久性引擎,该引擎将自动将类映射到数据库中的表,并将类的属性映射到表列。您可以从定义两个自定义属性开始

TableMappingAttribute
ColumnMappingAttribute
然后,您可以将其应用于您的类,例如,我们有一个Person类

[TableMapping("People")]
public class Person
{
  [ColumnMapping("fname")]
  public string FirstName {get; set;}

  [ColumnMapping("lname")]
  public string LastName {get; set;}
}
在编译时,除了编译器发出由自定义属性定义的附加元数据这一事实之外,其他几乎没有受到影响。但是,您现在可以编写一个PersistanceManager,它可以动态检查Person类实例的属性,并将数据插入People表,将FirstName属性中的数据映射到fname列,将LastName属性映射到lname列


关于属性实例的问题,并不是为类的每个实例创建属性实例。所有人员实例将共享TableMappingAttribute和ColumnMappingAttribute的相同实例。事实上,只有当您第一次实际查询属性时,才会创建属性实例。

想想属性是附加到类或方法定义(嵌入在程序集元数据中)的post

然后,您可以拥有一个processor/runner/inspector模块,该模块通过反射接受这些类型,查找这些post its并以不同的方式处理它们。这称为声明式编程。您可以声明一些行为,而不是在类型中为它们编写代码

  • 类型上的Serializable属性声明它是为序列化而构建的。然后,XmlSerializer可以接受此类的对象并执行必要的操作。您可以使用正确的post标记需要序列化/隐藏的方法
  • 另一个例子是努尼特。NUnit运行程序查看目标程序集中定义的所有类的[TestFixture]属性,以标识测试类。然后,它查找标记有[Test]属性的方法来标识测试,然后运行测试并显示结果
你可能想把你的大部分问题都回答了的问题和最后的一个例子通读一遍。虽然他们可以提取一个名为
审计(类型anyType)而不是复制该代码。示例通过检查属性“打印信息”。。但是你也可以用同样的方式做任何事情。

我以前在日常工作中没有使用属性,但我已经读过了。 我也做了一些测试,来支持我在这里要说的。如果我在任何地方错了,请随时告诉我:)

据我所知,属性并不像普通类那样起作用。当您创建应用它们的对象时,它们不会被实例化,而不是一个stati
void Main()
{
    Console.WriteLine("before class constructor");
    var test = new TestClass();
    Console.WriteLine("after class constructor");

    var attrs = Attribute.GetCustomAttributes(test.GetType()).Dump();
    foreach(var attr in attrs)
        if (attr is TestClassAttribute)
            Console.WriteLine(attr.ToString());
}

public class TestClassAttribute : Attribute
{
    public TestClassAttribute()
    {
        DefaultDescription = "hello";
        Console.WriteLine("I am here. I'm the attribute constructor!");
    }
    public String CustomDescription {get;set;}
    public String DefaultDescription{get;set;}

    public override String ToString()
    {
        return String.Format("Custom: {0}; Default: {1}", CustomDescription, DefaultDescription);
    }
}

[Serializable]
[TestClass(CustomDescription="custm")]
public class TestClass
{
    public int Foo {get;set;}
}
before class constructor
after class constructor
I am here. I'm the attribute constructor!
Custom: custm; Default: hello
[XmlRpcMethod("flexlabs.ProcessTask")]
public int ProcessTask_MyCustomName_BecauseILikeIt();
public class MyOwnAttributeClass : Attribute {
    public MyOwnAttributeClass() {
    }
    public MyOwnAttributeClass(string myName) {
        MyName = myName;
    }
    public string MyName { get; set; }
}
[MyOwnAttributeClass("MyCustomerName")]
public class Customer {
    [MyOwnAttributeClass("MyCustomerNameProperty")]
    public string CustomerName { get; set; }
}
Attribute[] attributes = typeof(Customer).GetCustomAttribute(typeof(MyOwnAttributeClass));