属性在面向对象中是比较重要的,比如说人有手有脚,手,脚都是人的属性这话说得对,在一般的面向对象是这样的。可是c#里面有多了一种东西,虽然也叫属性,可是挂羊头卖狗肉 如:[WebMethod] public string Service(XmlNode node) { return "Security WEB interface,Creating...."; }[WebMethod]就是属性,我不知道为啥加上这个属性Service这个方法就可以让客户端的程序来用了,也就是“属性”和它下面的方法/变量/...东西是如何来沟通的。还有自己也可以写属性,从System.Attribute 派生出来,可是不太明白里面的原理。总感觉有点像宏一样,微软自己搞出来的,如果不明白原理,总会是云里雾里的:(
帮助上找到一些如果没有检索自定义属性的信息和对其进行操作的方法,则定义自定义属性并将其放置在源代码中就没有意义。幸而 C# 具有反射系统,使您能够做到这些。主要方法是 GetCustomAttributes,它返回对象数组,这些对象在运行时相当于源代码属性。属性规范,如[Author("H. Ackerman", version=1.1)] class AClass {...} 在概念上等效于:Author anonymousAuthorObject = new Author("H. Ackerman"); anonymousAuthorObject.version = 1.1; 但是,直到对属性查询 AClass 时才执行此代码。在 AClass 上调用 GetCustomAttributes 会导致按上述方式构造并初始化一个 Author 对象。如果此类具有其他属性,会以相同的方式构造其他属性对象。然后,GetCustomAttributes 返回 Author 对象和数组中的其他任何属性对象。之后就可以对此数组进行迭代,确定根据每个数组元素的类型所应用的属性,并从属性对象中提取信息。示例 下面是一个完整的示例。定义一个自定义属性,将其应用于若干实体并通过反射进行检索。// cs_attributes_retr.cs using System; [AttributeUsage(AttributeTargets.Class|AttributeTargets.Struct, AllowMultiple=true)] public class Author : Attribute { public Author(string name) { this.name = name; version = 1.0; } public double version; string name; public string GetName() { return name; } }[Author("H. Ackerman")] class FirstClass { /*...*/ }class SecondClass // no Author attribute { /*...*/ }[Author("H. Ackerman"), Author("M. Knott", version=1.1)] class Steerage { /*...*/ }class AuthorInfo { public static void Main() { PrintAuthorInfo(typeof(FirstClass)); PrintAuthorInfo(typeof(SecondClass)); PrintAuthorInfo(typeof(Steerage)); } public static void PrintAuthorInfo(Type t) { Console.WriteLine("Author information for {0}", t); Attribute[] attrs = Attribute.GetCustomAttributes(t); foreach(Attribute attr in attrs) { if (attr is Author) { Author a = (Author)attr; Console.WriteLine(" {0}, version {1:f}", a.GetName(), a.version); } } } } 输出 Author information for FirstClass H. Ackerman, version 1.00 Author information for SecondClass Author information for Steerage H. Ackerman, version 1.00 M. Knott, version 1.10
另外,proerty其中可以实现一些逻辑
感觉就是方法和类的公共变量的中间体
对此有不同的说明:
1的作用:
更好体现封装-我们要使用一个类中的变量,如果没有属性,那就只好直接访问,这样必然要告诉编译器是那个类中的那个变量,可以想象一下,这样的操作实际就直接要深入到类中进行操作了.但是如果有了属性,就可以看成是类的一个接口,直接在类的外面就可以进行操作了.这样的一个变化,对于嵌套的类,可以带来更多的安全性.
2的作用
我的看法是仅仅起一个说明作用,就是告诉编译器这个属性下的操作是要调用api而已.
更改属性值时可以加入值的有效性判断,或者做一些相应的处理等;field就不行。
还可以引发一些事件或自定义事件
通过属性来交换数据
可以在 set属性时 判断 数据的有效性
这样增强了安全性
在类外部通过属性访问成员变量,这样在类外部隐藏了成员变量
有更好的封装性
如:[WebMethod]
public string Service(XmlNode node)
{
return "Security WEB interface,Creating....";
}[WebMethod]就是属性,我不知道为啥加上这个属性Service这个方法就可以让客户端的程序来用了,也就是“属性”和它下面的方法/变量/...东西是如何来沟通的。还有自己也可以写属性,从System.Attribute 派生出来,可是不太明白里面的原理。总感觉有点像宏一样,微软自己搞出来的,如果不明白原理,总会是云里雾里的:(
在概念上等效于:Author anonymousAuthorObject = new Author("H. Ackerman");
anonymousAuthorObject.version = 1.1;
但是,直到对属性查询 AClass 时才执行此代码。在 AClass 上调用 GetCustomAttributes 会导致按上述方式构造并初始化一个 Author 对象。如果此类具有其他属性,会以相同的方式构造其他属性对象。然后,GetCustomAttributes 返回 Author 对象和数组中的其他任何属性对象。之后就可以对此数组进行迭代,确定根据每个数组元素的类型所应用的属性,并从属性对象中提取信息。示例
下面是一个完整的示例。定义一个自定义属性,将其应用于若干实体并通过反射进行检索。// cs_attributes_retr.cs
using System;
[AttributeUsage(AttributeTargets.Class|AttributeTargets.Struct,
AllowMultiple=true)]
public class Author : Attribute
{
public Author(string name)
{
this.name = name; version = 1.0;
}
public double version;
string name;
public string GetName()
{
return name;
}
}[Author("H. Ackerman")]
class FirstClass
{
/*...*/
}class SecondClass // no Author attribute
{
/*...*/
}[Author("H. Ackerman"), Author("M. Knott", version=1.1)]
class Steerage
{
/*...*/
}class AuthorInfo
{
public static void Main()
{
PrintAuthorInfo(typeof(FirstClass));
PrintAuthorInfo(typeof(SecondClass));
PrintAuthorInfo(typeof(Steerage));
}
public static void PrintAuthorInfo(Type t)
{
Console.WriteLine("Author information for {0}", t);
Attribute[] attrs = Attribute.GetCustomAttributes(t);
foreach(Attribute attr in attrs)
{
if (attr is Author)
{
Author a = (Author)attr;
Console.WriteLine(" {0}, version {1:f}",
a.GetName(), a.version);
}
}
}
}
输出
Author information for FirstClass
H. Ackerman, version 1.00
Author information for SecondClass
Author information for Steerage
H. Ackerman, version 1.00
M. Knott, version 1.10
迷惑,字段也可以又智能检测,只要你设了get,set方法,
里面不是也可以有逻辑检查吗?
如果这样,那现在字段不就默认成了private属性吗?
(没有get,set方法,数据封装不能设为public)
属性的使用一般是被动的。
两个部分组成:
属性的颁发者和属性的使用者。属性的颁发者声明了某种意义。要求属性的使用者把符合该意义的构造型(类,成员,,)标记上它。
那么属性的颁发者,就能通过根据它们是否有标记属性,和属性的数据进行某种操作了。其中属性的颁发者是主动地,而属性的使用者是被动的。对于平时,我们和我们创建的类只做为属性的使用者。例如对于可序列化的对象,我们只是定义:
[Serilizable] public class NameInfo
{
private string n="Undefined";
public string Name
{
get
{
return n;
}
set
{
n=value;
}
}
}
又例如在WebService里用到的WebServiceAttribute和WebMethodAttribute什么时候我们才做属性的颁布者,实现自己的属性?对于一般的应用,属性是用不上的。通常的扩展都使用虚拟继承来实现。
只有当你做的东西有自己或其他人进行扩展时,才考虑使用自定义属性。我这里没法说得明白。下面放个容易理解为什么使用属性的例子吧:
(这个例子需要些反射的知识)using System;
using System.Reflection;using 定义;
using 颁发者;
using 使用者;
using 程序;namespace 定义
{
public interface IJob
{
void Work();
}
}namespace 颁发者
{
//定义一个Slow的属性。它只能使用在方法上 [AttributeUsage(AttributeTargets.Method)]
public class SlowAttribute:Attribute
{
string desc;
public SlowAttribute(string waitdesc)
{
desc=waitdesc;
}
public string WaitDescription
{
get
{
return desc;
}
}
}
}namespace 使用者
{
public class 学习DotNet : IJob
{
public void Work()
{
Console.WriteLine("-->学习完毕");
}
}
public class 精通DotNet : IJob
{
[Slow("很久")]
public void Work()
{
System.Threading.Thread.Sleep(3000);
Console.WriteLine("........................精通完毕");
}
}
}namespace 程序
{
public interface IJobExecutor
{
void Execute(IJob job);
} class Util
{
static public MethodInfo FindJobWork(IJob job)
{
InterfaceMapping map=job.GetType().GetInterfaceMap(typeof(IJob));
return map.TargetMethods[0];
}
} public class 浮躁的人 : IJobExecutor
{
public void Execute(IJob job)
{
MethodInfo mi=Util.FindJobWork(job);
bool isslow=mi.IsDefined(typeof(SlowAttribute),false);
if(!isslow)
{
job.Work();
Console.WriteLine("这么点小东西还难得到我?");
}
else
{
Console.WriteLine("靠,这么麻烦,老子不学了!!");
}
}
}
public class 耐心的人 : IJobExecutor
{
public void Execute(IJob job)
{
MethodInfo mi=Util.FindJobWork(job);
bool isslow=mi.IsDefined(typeof(SlowAttribute),false);
if(!isslow)
{
job.Work();
Console.WriteLine("努力,加油。");
}
else
{
SlowAttribute sa=(SlowAttribute)mi.GetCustomAttributes(typeof(SlowAttribute),false)[0];
Console.WriteLine("虽然做这个需要"+sa.WaitDescription+",但是我要把它完成。");
job.Work();
Console.WriteLine("哈哈。OK了");
}
}
}
}namespace ConsoleApplication1
{
class Class1
{
[STAThread]
static void Main(string[] args)
{
IJob j1=new 学习DotNet();
IJob j2=new 精通DotNet(); IJobExecutor exec1=new 浮躁的人();
IJobExecutor exec2=new 耐心的人(); Console.WriteLine();
Console.WriteLine("广播:浮躁的人的:");
Console.WriteLine(); Console.WriteLine("广播:学习:");
exec1.Execute(j1);
Console.WriteLine("广播:精通:");
exec1.Execute(j2); Console.WriteLine();
Console.WriteLine("广播:耐心的人的学习:");
Console.WriteLine(); Console.WriteLine("广播:学习:");
exec2.Execute(j1);
Console.WriteLine("广播:精通:");
exec2.Execute(j2);
}
}
}