首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > .NET > C# >

属性到底该如何理解?机制是如何样的

2011-12-10 
属性到底该怎么理解?机制是怎么样的?属性到底该怎么理解?机制是怎么样的?[STAThread]就指定为单线程,到底

属性到底该怎么理解?机制是怎么样的?
属性到底该怎么理解?机制是怎么样的?
[STAThread]就指定为单线程,到底是怎么控制的呢?

[解决办法]
同样 [STAThread],当即将运行一个Main函数时,运行时会首先检查到这个元数据,并且知道,开发人员希望以单线程模式运行Main函数。
[解决办法]
MSDN上这样说:
属性提供功能强大的方法以将声明信息与 C# 代码(类型、方法、属性等)相关联。一旦属性与程序实体关联,即可在运行时使用名为反射的技术对属性进行查询。

属性以两种形式存在:一种是在公共语言运行库的基类库中定义的属性,另一种是可以创建,可以向代码中添加附加信息的自定义属性。此信息可在以后以编程方式检索。

属性具有以下特点:
属性可向程序中添加元数据。元数据是嵌入程序中的信息,如编译器指令或数据描述。
程序可以使用反射检查自己的元数据。请参见使用反射访问属性。
通常使用属性与 COM 交互。

------------------------------
说白了,就是主要给程序添加元数据,然后在运行时通过“反射”获取这些元数据,以进行相应的操作。比如[STAThread]指示应用程序的线程模型是单线程单元。程序在开始运行的时候,会检查其线程模型,如果检测到其入口点属性中有[STAThread],就……否则就……。

[解决办法]
“属性”就是元数据。

元数据就是加入程序集(简单的说就是编译后exe、dll)中描述程序中数据结构的数据。

无论是在运行的时候还是静态的程序集,无论是外部加载者还是应用程序本身都可以访问元数据。

你的疑惑就是写在程序里面的属性在编译后怎么会影响应用程序的行为,举个例子说明你就明白了。比如STAThread属性,程序在加载时,应用程序的其他部分(不是你的程序,而是类库框架)可以找到你那个类的元数据,并且读出属性,然后控制应用程序的执行。

比如Browsable,VS环境加载你编译后的程序集,他也可以读出元数据,并且知道这个属性值,然后决定是否在对象观察器显示这个属性。
[解决办法]
其实如果你使用反射的话对属性应该有所了解的, 举个例子帮你理解属性是如何使用的,编译环境里面的类也是用了反射来判断你添加到类上的Attribute:
比如我们现在有个Diamond类,它包含字段price和weight,现在写个程序使其能按price排序,但是不久以后我又想用weight排序,我们可以定义一个Attribute来存储这两个选择,这个类继承于Attribute:
[AttributeUsage(AttributeTargets.Class)]
public class Order : Attribute
{
private string _order;
public Order(string orderColumn)
{
_order = orderColumn;
}

public string OrderCol
{
get { return _order; }
}
}

接着,我们为Diamond类定义Comare方法,并且将Attribute用在上面:
[Order( "Price ")]
public class Diamond : IComparable
{
private double _price;
private double _weight;

public Diamond(double price, double weight)
{
_price = price;
_weight = weight;
}

public string Details
{
get { return "Price: " + _price + " Weight: " + _weight; }
}

public double Weight
{
get { return _weight; }
}

public double Price
{
get { return _price; }
}

#region IComparable Members

public int CompareTo(object obj)
{
//Find the attribute defined on the class
Type diaType = typeof(Diamond);
object[]attrs = diaType.GetCustomAttributes(typeof(Order), false);
//if no attribute added use default method to order
string orderField = string.Empty;
if (attrs == null || attrs.Length == 0)
{
orderField = "Price ";
}
else
{
Order theOrder = attrs[0] as Order;
orderField = theOrder.OrderCol;
}

//When we read the field value, we can go with the compare
Diamond dia = obj as Diamond;
if (dia == null) throw new ArgumentException();
if (orderField == "Price ")
{

return dia.Price > = this.Price ? -1 : 1;
}
else if (orderField == "Weight ")


{
return dia.Weight > = this.Weight ? -1 : 1;
}
else
{
throw new ArgumentException();
}
}

#endregion
}

注意Compare中的方法是怎么获取定义在该类上的Order 这个Attribute的成员,这里使用了反射
最后让我们测试一下结果:
class Program
{
static void Main(string[] args)
{
ArrayList diamondCollection = new ArrayList();
Diamond a = new Diamond(100, 10);
Diamond b = new Diamond(150, 20);
Diamond c = new Diamond(80, 180);
Diamond d = new Diamond(170, 40);
diamondCollection.Add(a);
diamondCollection.Add(b);
diamondCollection.Add(c);
diamondCollection.Add(d);


diamondCollection.Sort();

foreach (Diamond m in diamondCollection)
{
Console.WriteLine(m.Details);
}
}
}

不管多复杂的程序,也是通过反射来获取定义在类上的Attribute的,最后提一点,你应该把它叫特性好点,属性一般是说Property的 :)

热点排行