gpt4 book ai didi

c# - 属性类如何工作?

转载 作者:IT王子 更新时间:2023-10-29 03:48:31 27 4
gpt4 key购买 nike

我的搜索一直只出现解释如何使用属性并将其应用于类的指南。我想了解如何创建自己的属性类及其工作原理。

属性类是如何实例化的?它们是在实例化它们所应用的类时实例化的吗?是否为每个实例化了它所应用的类实例化了一个?例如。如果我将 SerializableAttribute 类应用于 MyData 类,并实例化 5 个 MyData 实例,是否会在幕后创建 SerializbleAttribute 类的 5 个实例?还是只有一个实例在所有这些实例之间共享?

属性类实例如何访问它们关联的类? SerializableAttribute 类如何访问它所应用的类以便它可以序列化它的数据?它是否具有某种 SerializableAttribute.ThisIsTheInstanceIAmAppliedTo 属性? :) 或者它是否以相反的方向工作,每当我序列化某些东西时,我将 MyClass 实例传递给的序列化函数将反射性地遍历属性并找到 SerialiableAttribute 实例?

最佳答案

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

据我所知,属性不作为常规类。当您创建一个应用它们的对象时,它们不会被实例化,而不是一个静态实例,而不是每个对象实例 1 个。他们也不访问他们所应用的类..

相反,它们的行为类似于类的属性(特性?:P)。不像 .NET 类 properties,更像是“玻璃的一个属性是透明度”类型的属性。您可以通过反射检查将哪些属性应用于类,然后对其进行相应的操作。它们本质上是附加到类定义的元数据,而不是该类型的对象。

您可以尝试获取类、方法、属性等的属性列表。当您获取这些属性的列表时——这就是它们将被实例化的地方。然后您可以对这些属性中的数据进行操作。

例如在 Linq 表中,属性具有定义它们引用的表/列的属性。但是这些类不使用这些属性。相反,当 DataContext 将 linq 表达式树转换为 SQL 代码时,它会检查这些对象的属性。

现在来看一些真实的例子.. 我已经在 LinqPad 中运行了这些,所以不用担心奇怪的 Dump() 方法。我已将其替换为 Console.WriteLine 以使不了解它的人更容易理解代码:)

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

Attribute.GetCustomAttributes(test.GetType()) 返回此数组:(该表显示了所有条目的所有可用列。所以不,Serializable 属性没有这些属性:)) LinqPad Attributes Array

还有问题吗?欢迎提问!

更新:我看到你问了一个问题:为什么要使用它们?作为示例,我将向您介绍 XML-RPC.NET 库。您创建 XML-RPC 服务类,使用表示 xml-rpc 方法的方法。现在最主要的是:在 XmlRpc 中,方法名称可以有一些特殊字符,比如点。因此,您可以拥有一个 flexlabs.ProcessTask() xml rpc 方法。

您可以按如下方式定义此类:

[XmlRpcMethod("flexlabs.ProcessTask")]
public int ProcessTask_MyCustomName_BecauseILikeIt();

这允许我以我喜欢的方式命名方法,同时仍然使用必须的公共(public)名称。

关于c# - 属性类如何工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2676603/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com