我以前没有在日常工作中使用属性,但我读过它们。
我也做了一些测试,以支持我在这里说的话。如果我在任何地方错了 - 请随时告诉我:)
据我所知,属性并不是常规类。当您创建应用它们的对象时,它们不会被实例化,不是一个静态实例,不是每个对象实例 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 属性没有这些属性:))
还有其他问题吗?欢迎提问!
统一更新:
我看到你问过一个问题:为什么要使用它们?
作为一个例子,我将向您介绍 XML-RPC.NET 库。
您创建您的 XML-RPC 服务类,其方法将代表 xml-rpc 方法。现在主要的是:在 XmlRpc 中,方法名称可以有一些特殊字符,比如点。所以,你可以有一个 flexlabs.ProcessTask() xml rpc 方法。
你可以这样定义这个类:
[XmlRpcMethod("flexlabs.ProcessTask")]
public int ProcessTask_MyCustomName_BecauseILikeIt();
这允许我以我喜欢的方式命名方法,同时仍然使用它必须的公共名称。