Blue
Red
Green
Orange
Voilet
Slate
Dark

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

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

阿拉宁波人

Unregistered / Unconfirmed
GUEST, unregistred user!
Y

yysun

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.
 

阿拉宁波人

Unregistered / Unconfirmed
GUEST, unregistred user!
孙老师终于现身了,怪我没把问题描述清楚.
我问题是属性信息(attribute)不是属性(property).
就是用方括号括起来的那种,比如:
1. [assembly: AssemblyTitle("")]
2. [FieldName("abc")]
3. [WebMethod]
等等.
不太明白能否再解释一下。
 

四库全书

Unregistered / Unconfirmed
GUEST, unregistred user!
---------------- 展现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 标志中有效代码的机会。例如,由于种种原因(或根本没有原因),你
就能够拒绝一个新值。最好是没有人告诉你它是一个动态属性——当你第一次请求它后,它会保存下来,
故要尽可能地推迟资源分配。
 
D

dxcwxc

Unregistered / Unconfirmed
GUEST, unregistred user!
c# 的属性实际上是一种标签性质的东西,你可以自定义标签,在程序运行时可以获取标签
信息再做相关处理,在NANT(C#自动构建包)中的TASK实现体系,充分展现类ATTRIBLE的魅力
建议你去看一下其源码,最好对设计模式有点了解,看起来会比较快
 

阿拉宁波人

Unregistered / Unconfirmed
GUEST, unregistred user!
我说的不是这个吧?
[Browsable(true)] <<<< 我的意思是这种属性信息
[Description("A string object")] <<< ^^^^^^^^
[DefaultValue("")] <<<<
public string StringType
{
............
}
 
S

savenight

Unregistered / Unconfirmed
GUEST, unregistred user!
当然attribute可以存入任何信息,感觉好像有点抄袭Delphi的RTTI,我的理解就这么多了,说的不对请指正。
 
Y

yysun

Unregistered / Unconfirmed
GUEST, unregistred user!
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
 
S

savenight

Unregistered / Unconfirmed
GUEST, unregistred user!
人家说的不是你们说的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)中的其中一个。


 
L

lance2000

Unregistered / Unconfirmed
GUEST, unregistred user!
>>感觉好像有点抄袭Delphi的RTTI,
偶感觉也是.c#好象除了多了个装箱和拆箱没什么新鲜东西.
 

阿拉宁波人

Unregistered / Unconfirmed
GUEST, unregistred user!
我有点懂了,谢谢大家!
 

阿拉宁波人

Unregistered / Unconfirmed
GUEST, unregistred user!
多人接受答案了。
 
顶部 底部