• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    迪恩网络公众号

C#无参属性

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

大家来讨论下C#无参属性这个东西到底有没有存在的必要?

永远不要公开类型的字段,面向对象设计和编程的重要原则之一就是 数据封装。如果公开类型的字段,会很容易的写出不恰当使用字段的代码。这里可以把字段声明为private,然后声明访问器方法。

    class test
{

private string Name;
public void SetName(string value)
{
Name = value;
}
public string GetName()
{
return Name;
}

}

实现只读或只写就是这么简单,不实现一个索引器方法就行了。还可以将Setname方法标记为protected,就可以只允许派生类修改了。聪明的你也发现上面这个做法的缺点了吧,首先得去实现额外的方法,所以会产生更多的代码,其次,如果调用的时候必须调用方法,不能直接引用一个字段名。还好C#给我们提供了一个称为属性(property)的机制,它缓解了第一个缺点造成的影响,也消除了第二个缺点。

   class test
{

private string name;
public string Name {
get { return name; }
set { if ("狗剩" == value) { Console.WriteLine("系统崩溃,抛出异常"); return; } name = value; }
}

}

属性可以用任意的可访问修饰符来标记。不能定义名称相同的属性。

如果只是为了封装一个支持字段而创建属性,C#还提供一一种更简单的语法,称为自动实现的属性(Automatically Implemented Property,简称AIP)。like this

   class test
{
public int Age
{
get;
set;
}
}

如果声明一个属性而不提供get/set实现,C#会自动为你声明一个私有字段。原始代码是这样的:

public int Age
{
[CompilerGenerated]
get
{
int num;
num = this.<Age>k__BackingField;
Label_0009:
return num;
}
[CompilerGenerated]
set
{
this.<Age>k__BackingField = value;
return;
}
}

和直接声明一个public 的Age字段相比,自动实现的属性的优势在哪?两者存在一处重要的区别:使用自动实现的属性(AIP)意味着已经创建一个属性,访问该属性的时候会调用get/set方法。如果有一天你决定自己实现这个AIP的get/set,而不接受编译器默认的实现,那么访问这个属性的任何代码都不必重新编译。如果是一个public的Age字段,如果你把它更改为属性,那么访问这个字段的所有代码就都需要重新编译了。

凡事都有好有坏,那么AIP有哪些不讨人喜欢的地方呢

1.如果使用字段声明的语法,可以包含初始化的部分,如果使用AIP就不行了,必须在咩个构造器中显示的初始化每个AIP。

2.AIP支持的字段名是由编译器决定的,而且每次重新编译,这个字段名可能会发生更改,这样一来,只要含有一个AIP就不能对类型的实例进行反序列化了。在任何想要序列化或反序列化的类型中,都不要使用AIP功能。

3.不能在AIP的get/set添加断点,所以不好检测程序在什么时候获取或设置这个属性。咱手动实现的就可以设置断点,不信你试试。

AIP功能是作用于整个属性的:要么都用,要么都不用,这意味这,如果显式的实现get那么set也要显式实现,反之亦然。

 

属性看起来与字段相似,但本质上是方法。属性与字段的区别如下:

1.属性可以是只读或只写的(get/set访问器方法),字段却总是可读可写的。

2.属性方法可能抛出异常,字段访问不会抛出。

3.属性不能作为out或ref参数传递给方法,字段可以。

class Program
{
public int Age
{
get {return 3 ;}
set{}
}
int age;
static void Main()
{
var t = new { name="XiaoBai",age=22 };
test tt = new test();
//tt.Name = "狗剩";
Program p = new Program();
some(out p.age);
some(out p.Age);//属性,索引器或动态成员不得作为out或ref参数传递
Console.ReadKey();
}
static void some(out int age)
{
age = 10;
}
}

4.属性方法可能花费较长时间执行,字段的访问都是立即完成。

5.属性方法可能需要额外的内存,或者返回一个不正确的引用,指向不属于对象状态一部分的某个东西,这样一来,对返回对象的修改就作用不到原始对象身上了,相反查询字段返回的总是正确的引用,它指向的东西保证是原始对象状态的一部分。使用会返回一个拷贝的属性时,非常容易引起混淆。

如果仔细研究下属性和字段的差别,你会发现只有在极个别的情况下属性才真正有用。属性唯一的好处就是提供了简化的语法,和调用普通方法(非属性中的方法)相比,属性不仅不会提升代码的性能,还会妨碍对代码的理解。

属性访问器的可访问性:

我们有时希望为get访问器指定一种可访问性,为set访问器指定另一种访问器:

    class test
{
public int Age
{
get { return age; }
protected set { if (value < 0) Console.WriteLine("年龄错误!"); else { age = value; } }
}
int age;
}

如上所述,Age属性本身声明为public,意味这get访问器方法是公共的,可由所有代码访问,但是,注意set访问器方法被声明为protected,只能从test的内部定义的代码中调用,或者从test的派生类的代码中调用。

定义一个属性时,如果两个访问其方法需要具有不同的可访问性,C#语法要求必须为属性本身指定限制最不大的那一种可访问性,然后在两个访问其中,只能选择一个来应用限制较大的那一种可访问性。在前面的例子中,属性本身为public,set访问器为protected(限制比public大)。

   class test
{
private int Age
{
get { return age; }
protected set { if (value < 0) Console.WriteLine("年龄错误!"); else { age = value; } }//这里就通不过编译
}
int age;
}





鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
ASP.NETC#DataTable与Excel互操作示例发布时间:2022-07-18
下一篇:
C#中int、long、float、double、decimal最大值最小值发布时间:2022-07-18
热门推荐
热门话题
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap