C#中Property和Attribute的区别

 我来答
硪丨暧恋
2017-07-12 · TA获得超过8980个赞
知道大有可为答主
回答量:5336
采纳率:93%
帮助的人:2202万
展开全部
在C#中有两个属性,分别为Property和Attribute,两个的中文意思都有特性、属性之间,但是用法上却不一样,为了区别,本文暂把Property称为特性,把Attribute称为属性。
Attribute才是本文的主角,把它称为属性我觉得很恰当。属性的意思就是附属于某种事物上的,用来说明这个事物的各种特征的一种描述。而Attribute就是干这事的。它允许你将信息与你定义的C#类型相关联,作为类型的标注。这些信息是任意的,就是说,它不是由语言本身决定的,你可以随意建立和关联任何类型的任何信息。你可以作用属性定义设计时信息和运行时信息,甚至是运行时的行为特征。关键在于这些信息不仅可以被用户取出来作为一种类型的标注,它更可以被编译器所识别,作为编译时的一种附属条件参加程序的编译。
以下部分内容及代码来源于《C#技术揭秘》(Inside C# Sencond Edition)

定义属性:
属性实际上是一个派生自System.Attribute基类的类。System.Attribute类含有几个用于访问和检查自定义属性的方法。尽管你有权将任何类定义为属性,但是按照惯例来说,从System.Attribute派生类是有意义的。示例如下:
public enum RegHives
{
HKEY_CLASSES_ROOT,
HKEY_CURRENT_USER,
HKEY_LOCAL_MACHINE,
HKEY_USERS,
HKEY_CURRENT_CONFIG
}

public class RegKeyAttribute : Attribute
{
public RegKeyAttribute(RegHives Hive, String ValueName)
{
this.Hive = Hive;
this.ValueName = ValueName;
}

protected RegHives hive;
public RegHives Hive
{
get { return hive; }
set { hive = value; }
}

protected String valueName;
public String ValueName
{
get { return valueName; }
set { valueName = value; }
}
}
我们在这里添加了不同注册表的枚举、属性类的构造器以及两个特性(Property)。在定义属性时你可以做许许多多的事情,下面我们看看如何在运行时查询属性。要想在运行时查询类型或成员所附着的属性,必须使用反射

查询类属性:
假设你希望定义一个属性,这个属性定义了将在其上创建对象的远程服务器。如果没有这个属性,就要把此信息保存在一个常量中或是一个应用程序的资源文件中。通过使用属性,只需用以下方法标注出类的远程服务器名即可:
using System;

namespace QueryAttribs
{
public enum RemoteServers
{
JEANVALJEAN,
JAVERT,
COSETTE
}

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);
}
}
}

[RemoteObject(RemoteServers.COSETTE)]
class MyRemotableClass
{
}
class Test
{
[STAThread]
static void Main(string[] args)
{
Type type = typeof(MyRemotableClass);
foreach (Attribute attr in
type.GetCustomAttributes(true))
{
RemoteObjectAttribute remoteAttr =
attr as RemoteObjectAttribute;
if (null != remoteAttr)
{
Console.WriteLine(
"Create this object on {0}.",
remoteAttr.Server);
}
}

Console.ReadLine();
}
}
}
运行结果为:
Creat this object on COSETTE。
注意:在这个例子中的属性类名具有Attribute后缀。但是,当我们将此属性附着给类型或成员时却不包括Attribute后缀。这是C#语言的设计者提供的简单方式。当编译器看到一个属性被附着给一个类型或成员时,它会搜索具有指定属性名的System.Attribute派生类。如果编译器没有找到匹配的类,它就在指定的属性名后面加上Attribute,然后再进行搜索。因此,常见的使用做法是将属性类名定义为以Attribute结尾,在使用时忽略名称的这一部分。以下的代码都采用这种命名方式。
查询方法属性:
在下面这个例子中,我们使用属性将方法定义为可事务化的方法,只要存在TransactionableAttribute属性,代码就知道具有这个属性的方法可以属于一个事务。
using System;
using System.Reflection;

namespace MethodAttribs
{
public class TransactionableAttribute : Attribute
{
public TransactionableAttribute()
{
}
}

class SomeClass
{
[Transactionable]
public void Foo()
{}

public void Bar()
{}

[Transactionable]
public void Goo()
{}
}

class Test
{
[STAThread]
static void Main(string[] args)
{
Type type = Type.GetType("MethodAttribs.SomeClass");
foreach (MethodInfo method in type.GetMethods())
{
foreach (Attribute attr in
method.GetCustomAttributes(true))
{
if (attr is TransactionableAttribute)
{
Console.WriteLine(
"{0} is transactionable.",
method.Name);
}
}
}

Console.ReadLine();
}
}
}
运行结果如下:
Foo is transactionable.
Goo is transactionable.
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式