谁能解释一下c#中属性信息的作用与用法?(50分)

  • 主题发起人 主题发起人 阿拉宁波人
  • 开始时间 开始时间

阿拉宁波人

Unregistered / Unconfirmed
GUEST, unregistred user!
Properties are accessors for private fields.
A property is a virtual field, looks like a field, but is implemented with code.
Properties can be:read-only, write-only, or read/write
public class Button: Control {
private string caption;
public string Caption {
get { return caption;
}
set { caption = value;
Repaint();
}
}
}
Button b = new Button();
b.Caption = "OK";
String s = b.Caption;
The example above shows that when assigning value to the "Caption" property, the
Repaint() method will be triggered.
 
孙老师终于现身了,怪我没把问题描述清楚.
我问题是属性信息(attribute)不是属性(property).
就是用方括号括起来的那种,比如:
1. [assembly: AssemblyTitle("")]
2. [FieldName("abc")]
3. [WebMethod]
等等.
不太明白能否再解释一下。
 
---------------- 展现c# --------------------------
有两种途径揭示类的命名属性——通过域成员或者通过属性。前者是作为具有公共访问性的成员变量而被
实现的;后者并不直接回应存储位置,只是通过存取标志(accessors)被访问。
当你想读出或写入属性的值时,存取标志限定了被实现的语句。用于读出属性的值的存取标志记为关键字
get,而要修改属性的值的读写符标志记为set。在你对该理论一知半解以前,请看一下清单5.9 中的例子,
属性SquareFeet 被标上了get 和set 的存取标志。
清单5.9 实现属性存取标志
1: using System;
2:
3: public class House
4: {
5: private int m_nSqFeet;
6:
7: public int SquareFeet
8: {
9: get { return m_nSqFeet;
}
10: set { m_nSqFeet = value;
}
11: }
12: }
13:
14: class TestApp
15: {
16: public static void Main()
17: {
18: House myHouse = new House();
19: myHouse.SquareFeet = 250;
20: Console.WriteLine(myHouse.SquareFeet);
21: }
22: }
展现C#

House 类有一个命名为SquareFeet 的属性,它可以被读和写。实际的值存储在一个可以从类内部访问的变
量中——如果你想当作一个域成员重写它,你所要做的就是忽略存取标志而把变量重新定义为:
public int SquareFeet;
对于一个如此简单的变量,这样不错。但是,如果你想要隐藏类内部存储结构的细节时,就应该采用存取
标志。在这种情况下,set 存取标志给值参数中的属性传递新值。(可以改名,见第10 行。)
除了能够隐藏实现细节外,你还可自由地限定各种操作:
get 和set:允许对属性进行读写访问。
get only:只允许读属性的值。
set only:只允许写属性的值。
除此之外,你可以获得实现在set 标志中有效代码的机会。例如,由于种种原因(或根本没有原因),你
就能够拒绝一个新值。最好是没有人告诉你它是一个动态属性——当你第一次请求它后,它会保存下来,
故要尽可能地推迟资源分配。
 
c# 的属性实际上是一种标签性质的东西,你可以自定义标签,在程序运行时可以获取标签
信息再做相关处理,在NANT(C#自动构建包)中的TASK实现体系,充分展现类ATTRIBLE的魅力
建议你去看一下其源码,最好对设计模式有点了解,看起来会比较快
 
我说的不是这个吧?
[Browsable(true)] <<<< 我的意思是这种属性信息
[Description("A string object")] <<< ^^^^^^^^
[DefaultValue("")] <<<<
public string StringType
{
............
}
 
当然attribute可以存入任何信息,感觉好像有点抄袭Delphi的RTTI,我的理解就这么多了,说的不对请指正。
 
Sorry for the misunderstanding.
In order to know Attibute, you'd first know what is metadata.
.NET compiles source code and produces metadata and Microsoft Intermediate
Language (MSIL) code. Metadata includes a complete specification for a program
including all its types, apart from the actual implementation of each function.
Attibute is used to set the metadata.
Through Reflection, you can retreive the metadata.
http://www.oreillynet.com/pub/a/dotnet/excerpt/prog_csharp_ch18
 
人家说的不是你们说的property,是Attribute.
Attribute是从System.Attribute继承来的一个类,我觉得它主要是产生自描述信息。
[red]不好意思写的不够全面,修改一下。[/red]
Inside C#中有一个例子,(具体可以参见原文第八章,下面的内容在书中全可以找到):
Attributes可以分为Class Attributes,Method Attributes和 Field Attributes 三种。
1.Class Attributes
////////////////////////////////////////////////////////////////////////////
using System;
public enum RemoteServers
{
JEANVALJEAN,
JAVERT,
COSETTE
}
//下面实现了一个Attribute的子类RemoteObjectAttribute
public class RemoteObjectAttribute : Attribute
{
public RemoteObjectAttribute(RemoteServers Server)
{
this.server = Server;
}
protected RemoteServers server;
public string Server
{
get
{
return RemoteServers.GetName(typeof(RemoteServers),
this.server);
}
}
}
//这里应用RemoteObjectAttribute
[RemoteObjectAttribute(RemoteServers.COSETTE)]
class MyRemotableClass
{
}
////////////////////////////////////////////////////////////////////////////
//下面是怎样‘query’ RemoteObjectAttribute
class ClassAttrApp
{
public static void Main()
{
Type type = typeof(MyRemotableClass);
foreach (Attribute attr in type.GetCustomAttributes())
{
RemoteObjectAttribute remoteAttr =
attr as RemoteObjectAttribute;
if (null != remoteAttr)
{
Console.WriteLine("Create this object on {0}.",
remoteAttr.Server);
//这里输出‘Create this object on COSETTE.’
}
}
}
}
========================================
2.Method Attributes
////////////////////////////////////////////////////////////////////////////
using System;
using System.Reflection;
public class TransactionableAttribute : Attribute
{
public TransactionableAttribute()
{
}
}
class TestClass
{
[Transactionable]
public void Foo()
{}
public void Bar()
{}
[Transactionable]
public void Baz()
{}
}
class MethodAttrApp
{
public static void Main()
{
Type type = Type.GetType("TestClass");
foreach(MethodInfo method in type.GetMethods())
{
foreach (Attribute attr in
method.GetCustomAttributes())
{
if (attr is TransactionableAttribute)
{
Console.WriteLine("{0} is transactionable.",
method.Name);
//这里输出‘Foo is transactionable.
// Baz is transactionable.’
}
}
}
}
}
========================================
3.Field Attributes
////////////////////////////////////////////////////////////////////////////
using System;
using System.Reflection;
public enum RegistryHives
{
HKEY_CLASSES_ROOT,
HKEY_CURRENT_USER,
HKEY_LOCAL_MACHINE,
HKEY_USERS,
HKEY_CURRENT_CONFIG
}
public class RegistryKeyAttribute : Attribute
{
public RegistryKeyAttribute(RegistryHives Hive, String ValueName)
{
this.Hive = Hive;
this.ValueName = ValueName;
}
protected RegistryHives hive;
public RegistryHives Hive
{
get { return hive;
}
set { hive = value;
}
}
protected String valueName;
public String ValueName
{
get { return valueName;
}
set { valueName = value;
}
}
}
class TestClass
{
[RegistryKey(RegistryHives.HKEY_CURRENT_USER, "Foo")]
public int Foo;
public int Bar;
}
class FieldAttrApp
{
public static void Main()
{
Type type = Type.GetType("TestClass");
foreach(FieldInfo field in type.GetFields())
{
foreach (Attribute attr in field.GetCustomAttributes())
{
RegistryKeyAttribute registryKeyAttr =
attr as RegistryKeyAttribute;
if (null != registryKeyAttr)
{
Console.WriteLine
("{0} will be saved in {1}////{2}",
field.Name,
registryKeyAttr.Hive,
registryKeyAttr.ValueName);
}
}
}
}
}
++++++++++++++++++++++++++++++++++++++++
另外Attribute的参数还可以缺省,就像delphi的一样,具体请参看原文;
还有一个注意的就是可以利用AttributeUsage 来规定Attribute的用法,比如默认情况下同一个Attribute
不可以出现两次,
public class SingleUseAttribute : Attribute
{
public SingleUseAttribute(String str)
{
}
}
// ERROR: This results in a "duplicate attribute" compiler error.出错了
[SingleUse("abc")]
[SingleUse("def")]
class MyClass
{
}
如果改成下面的样子就没错了
[AttributeUsage(AttributeTargets.All, AllowMultiple=true)]
public class SingleUseAttribute : Attribute
{
public SingleUseAttribute(String str)
{
}
}
[SingleUse("abc")]
[SingleUse("def")]
class MyClass
{
}
+++++++++++++++++++++++++++++++++++++++++
最后一个介绍的是Attribute Identifiers。
class MyClass
{
[HRESULT]
public long Foo();
}
上面这种情况你知道Attribute 是描述Foo方法呢,还是描述返回值呢?为了明确描述的对象,可以这样:
class MyClass
{
[return:HRESULT]
public long Foo();
}
return是属于Attribute Identifiers(包括assembly,module ,type ,method ,property ,event ,field , param, return)中的其中一个。


 
>>感觉好像有点抄袭Delphi的RTTI,
偶感觉也是.c#好象除了多了个装箱和拆箱没什么新鲜东西.
 
我有点懂了,谢谢大家!
 
多人接受答案了。
 
后退
顶部