CLR via C#:属性

属性:属性可以看成是智能字段。具有以下特性:
1.属性可以使用任何可访问性修饰符。
2.属性返回类型和参数类型不能为void。
3.属性不能作为out或者ref参数传递。
4.C#提供get(元数据为get_属性名)访问器函数用来获取字段值;提供set(元数据为set_属性名)访问器函数用来修改字段值;提供属性函数用来包含get和set访问器函数。开发人员在属性函数中至少要实现get和set当中一个访问器函数。
5.访问器函数的可访问性修饰符默认跟属性函数的可访问性修饰符一样。只有同时存在get和set访问器函数时,才能对其中一个访问器函数使用比属性函数的可访问性修饰符的限制性还要大的可访问性修饰符。
6.C#中不支持泛型属性访问器函数,因为支持的话就有可能改变对象的行为,而如果要改变对象行为的话,最好用方法而非属性。
7.访问器函数中操作的字段称为支持字段。通常将支持字段设置成私有的,从而防止外界修改造成未知异常。
8.当按照使用字段的方式来使用属性时,编译器会根据托管程序集中属性定义项数据信息找到对应的get或者set访问器函数。
9.set访问器函数中包含一个对支持字段进行赋值的隐藏value参数。
10.自动实现属性指的是属性函数中必须包含“get;”且C#自动为程序员生成一个私有字段(字段名为"<属性名>k__BackingField")以及一个get访问器函数来操作该私有字段;如果属性函数中还包含"set;"的话,C#还会生成一个set访问器函数来操作该私有字段。在需要字段声明时初始化以及字段序列化的情况下不要使用自动实现属性这个功能。
11.由于线程同步或者MashaByRefObject(用于远程访问)派生类中使用属性可能花较长的时间执行,从而造成程序终止,所以不建议在这种情况下使用属性。

无参属性:包含上面属性特性外,还具有以下特性:
1.get访问器函数不接收参数;set访问器函数接收一个隐藏的value参数。
2.不支持重载,也就是不能有同名属性。
3.属性可以应用于静态属性,实例属性,抽象属性,虚属性。

有参属性: 包含上面属性特性外,还具有以下特性:
1.get访问器函数接收一个或多个参数;set访问器函数接收两个或多个参数(包含隐藏的value参数)。
2.在C#中属性名有且只有一个,要么是默认的Item,要么是IndexerNameAttribute定制特性指定的属性名。不论哪种属性名,在代码中都是this。
3.在VB中属性名可以有多个,开发人员必须用DefaultMemberAttribute定制特性来标识其他编程语言(如C#)唯一能访问的属性名。
4.C#以数组风格的语法来公开参数列表(不包含隐藏的value参数),如"this[int a, string b, float c, …]"。其中"实例对象[int值,string值,float值, …]"会调用get访问器函数;"实例对象[int值,string值,float值, …]=value"会调用set访问器函数。
5.支持重载,只要参数列表不同即可。
6.属性可以应用于实例属性,抽象属性,虚属性。
7.JIT编译器在运行时会对简单的get和set访问器函数进行内联操作,从而提高属性的执行效率。

对象初始化器:指的是调用实例构造函数创建对象并设置对象的一些公共属性或者字段。具有以下特性:
1>.当调用的是无参实例构造函数时,"()"可以省略掉。
2>.当属性类型是非集合类型的话,初始化是一种替换操作(也就是调用属性的set访问器函数来替换关联字段的值)。代码如下所示:

String str = new Employee() { Name = "zjz", Age = 18 }.ToString().ToUpper()

等价于:

String str = new Employee { Name = "zjz", Age = 18 }.ToString().ToUpper()

等价于

Employee e = new Employee();
e.Name = "zjz";
e.Age = 18
String str = e.ToString().ToUpper();

3>.当属性是集合类型(也就是实现了IEnumerable或者IEnumerable接口)的话,初始化是一种相加操作(也就是先调用属性的get访问器函数来获取关联的集合字段;然后调用集合字段的Add函数来添加值)。代码如下所示:

public sealed class ClassRoom
{
	private List<string> m_students = new List<string>();
	// 集合类型的属性
	public List<string> Students
	{
		get
		{
			return m_students;
		}
	}
}

ClassRoom classroom = new ClassRoom() { Students = { "zjz", "yy"} };
等价于:
```csharp
ClassRoom classroom = new ClassRoom { Students = { "zjz", "yy"} };

等价于

ClassRoom classroom = new ClassRoom();
classroom.Students.Add("zjz");
classroom.Students.Add("yy");

匿名类型:指的是new关键字后面不指定具体类型,经常与LINQ配合使用。具有以下特性:
1.表达式格式为:

var o = new { p1=e1, ..., pn=en };

2.编译器生成为:

[CompilerGenerated]
internal sealed class <>f__AnonymousType0<...>: Object
{
	private readonly t1 f1;
	public t1 p1
	{
		get
		{
			return f1;
		}
	}
	...
	private readonly tn fn;
	public tn pn
	{
		get
		{
			return fn;
		}
	}
	
	public <>f__AnonymousType0<...>(t1 e1, ..., tn en)
	{
		f1=e1;
		...
		fn=en
	}
	
    public override Boolean Equals(Object value)
    {
    	// 任何一个字段不同就返回false,否则就返回true
    }
     
	public override Int32 GetHashCode()
	{
		// 返回根据每个字段的哈希码生成的一个哈希码
	}

	public override String ToString()
	{
		// 返回以"属性名=值"对的以逗号分隔的列表
	}
}

3.编译器执行流程为:
1>.推断每个表达式的类型并创建推断类型的私有字段。
2>.为每个私有字段生成公共只读属性,从而防止对象哈希码发生变化。
3>.创建一个实例构造函数来接收所有表达式,然后在该函数内部用表达式的值来初始化同表达式类型的私有字段。
4>.重写Object类型的Equals和GetHashCode函数,从而可以将匿名类型对象放入到哈希表集合中。
5>.重写Object类型的ToString函数来帮助开发人员进行调试。
4.当表达式使用局部变量时,推断的属性就等价于该局部变量。如下所示:

String Name = "zjz";
Int32 Age = 20
var o = new { Name, Age }

等价于表达式

var o = new { Name="zjz", Age=20 }

5.当存在多个相同结构(也就是匿名类型中每个属性具有相同的顺序,名称和类型)时,编译器也只生成一个匿名类型。
6.匿名类型不能在函数外面使用,也不能在函数参数和返回结果处使用。

元组类型:由.NET提供的一种最多存储8个元素的类型,其结构跟匿名类型相似。具有以下特性:
1>.元祖中前7个属性的名字叫做Item#(#代表数字),第8个属性名字叫做Rest;每个私有字段的名字都是由对应的属性自动生成。所以开发人员应该写好注释来表明每个属性的具体含义是什么,从而方便使用和后期维护。
2.元祖中的属性都是公有只读类型,不允许外界改变元祖对象的哈希码。
3.元祖中第8个属性类型是包含一个任意元素的Tuple类型。

ExpandoObject类型:等价于一个Dictionary<String, Object>字典类型,允许开发人员在运行时任意设置字典成员。代码如下所示:

// 运行时创建ExpandoObject对象
dynamic o = new ExpandoObject()
o.x = 6;
o.y = "zjz";
o.z = 20
// 运行时访问ExpandoObject对象
foreach(var v in (IDictionary<String, Object>)o)
{
	Console.WriteLine("Key={0}, Value={1}", v.Key, v.Value);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值