我以前在日常工作中没有使用过属性,但我读过一些关于它们的内容。同时我也做了一些测试来证实我在这里要说的内容。如果我在任何地方都是错的,请随时告诉我:
据我所知,属性不像普通类那样起作用。它们在你创建一个应用该属性的对象时不会被实例化,也不会有一个静态实例或每个对象实例都有一个实例。它们也不会访问应用该属性的类。
相反,它们就像类的属性(属性?:P)一样。并不像.NET类的属性,更像“玻璃的一个属性是透明性”这种属性。您可以从反射中检查应用到类上的属性,然后根据需要进行操作。它们本质上是附加到类定义的元数据,而不是该类型的对象。
您可以尝试获取类、方法、属性等的属性列表。当你获取这些属性列表时,它们将被实例化。然后您可以对这些属性中的数据进行操作。
例如,Linq表格、属性上有定义它们指向哪个表/列的属性。但这些类不使用这些属性。取而代之的是,当DataContext将查询表达式树转换为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
而Attribute.GetCustomAttributes(test.GetType())
返回这个数组:
(该表格显示了所有条目的所有可用列...因此,Serializable属性没有这些属性 :) )
![LinqPad Attributes Array](https://lh5.ggpht.com/_uVsNX7rt1gI/S83pI68M2hI/AAAAAAAAAIQ/fXeVFoTZdKg/Attributes.PNG)
还有其他问题吗?请随意提问!
更新:
我看到你问了一个问题:为什么要使用它们?
以XML-RPC.NET库为例。
您创建自己的XML-RPC服务类,并使用方法来表示xml-rpc方法。现在最重要的是:在XmlRpc中,方法名称可以具有某些特殊字符,例如句点。因此,您可以拥有一个flexlabs.ProcessTask() xml rpc方法。
您可以按如下方式定义此类:
[XmlRpcMethod("flexlabs.ProcessTask")]
public int ProcessTask_MyCustomName_BecauseILikeIt()
这使我可以按照自己的喜好命名方法,同时仍然使用公共名称,因为必须如此。