[C#详解] (1) 自动属性、初始化器、扩展方法

时间:2023-01-13 17:19:54

文章来源:Slark.NET-博客园 http://www.cnblogs.com/slark/p/CSharp-focus-1.html

代码下载:点我下载

目录

前言

首先祝大家2015新年快乐!

新的一年,新的开始。来博客园安家已经快两个月了。每天看博客、写博客、评论、回答博问已经渐渐养成了一种习惯。可以很明显的感觉到泡在博客园里真的可以学到很多,不论是技术文章的还是一些记叙经历、抒发感想的随笔,都让我从各个方面受益良多。不知道大家是否和我一样,就是感觉博客园有一种特殊的魔力,让你没事就想上去看一眼,看上面是不是又有人发了新文章,而且累了的时候在上面看看非技术的东西也能放松自己。

有时会问自己:在博客园上花了这些时间和精力,是否值得?毕竟这也算是"义务劳动",不为自己创造任何价值,通俗点说就是不挣钱。但是每想一次这个问题我都会更加坚定自己的选择。坚持博客园的理由有三:

  • 不断地利用博客园中的技术知识提高自己的技术水平,这无疑是在增加自身的价值。我觉得要想拿高工资,最本质的问题就是提高自身价值。对于我们技术人员来讲,就是知识面越广、掌握的技术越深入、编码的速度越快、质量越高、解决难题的问题越强,我们的价值就越高。博客园在这些方面对我们都是有帮助的。
  • 博客园中的非技术博客和新闻,让我们可以了解到同行业的人的工作、生活以及感情状态。并能针对程序员提供对口的业界新闻。这样可以让我对自己、以及同行业的人、包括整个行业有了更加清楚的认识。它让我对自己在行业中所处的地位有一个更加清晰的认识,这样一来可以更加准确的把握自己,更好的规划自己的职业生涯。
  • 博客园是一个展示的舞台。我看到很多博客里有发自己公司的招聘广告,或者推销自己的产品、自己的网站。没错,他们用这个优质的程序员聚集的平台,为自己打广告,而且还是免费的。这何乐而不为呢。对于目前的我来说,暂时还不需要广告什么,但是通过博客让更多的人认识我,了解到我的技术水平,肯定有百利而无一害的。免费给自己做广告,怎么看都是赚的。

因此,坚持博客园绝对是一个现实的决定。我相信我能一直做下去。

回到我们的博客本身。之前写了10篇MVC5 + EF6 + Bootstrap3系列教程,今年会继续写下去。毕竟这三项技术都是我大大看好的。在写这个系列的时候,有些遗憾的是,很多C#本身的技术点与MVC关系不大。详细写的话怕跑题,不写怕读者看不懂,一直都有点尴尬。因此我新开了这个专题[C#详解]来把那些曾经要讲而没有讲的东西一一讲讲清楚。这样自己也安心了。因此看了[C#详解]系列会使你在看MVC5 + EF6 + Bootstrap3系列时更加清楚明白。而看[C#详解]时也可以去MVC5 + EF6 + Bootstrap3找到这些知识点的实际应用场景。这样相辅相成,效果应该很好。

属性与自动属性

在解释自动属性之前有必要先说说属性。

属性

我们知道要符合面向对象编程的原则,一个类里面的变量最好是私有的。如下所示:

class Student
{
private int _id;
}

这样保证了类的封装性。可是把它封装起来总得有办法从外部访问它,要不然就没有存在的必要了。因此这里我们就用到了属性。代码如下所示:

 class Student
{
private int _id;
public int Id
{
get
{
return _id;
}
set
{
_id = value;
}
}
}

上面代码中第4行定义了一个名为Id的属性,通过它就能访问到私有变量_id。Id属性内部有get和set两个访问器,get访问器用于获取私有变量的值,set访问器用于给私有变量赋值。下面的代码展示如何使用属性:

 Student student = new Student();
student.Id = ;
Console.Write(student.Id);

第2行调用set访问器给Id赋值,第3行,调用get访问器获取Id值显示出来,结果如下:

[C#详解] (1) 自动属性、初始化器、扩展方法

属性的功能不仅如此,我们可以给get访问器加入代码来对输出做处理或者给set加入代码来对赋值做处理。示例如下:

 class Student
{
private int _id;
public int Id
{
get
{
return _id + ;
}
set
{
if (value > )
{
_id = value;
}
else
{
_id = ;
}
}
}
}

第8行的代码使Id属性在输出时加100,第12-19行,使Id属性在赋值时若值小于0,则赋值为0。

用下面代码调用上面的类。

 Student student = new Student();
student.Id = -;
Console.Write(student.Id);

第二行执行后Id属性会赋值为0,然后在输出时会变为100。

自动属性

属性的定义是繁琐的,这里我们就可以用自动属性来简化代码。同样是定义一个对输入输出不做任何特殊处理的属性,我们可以这样写:

 class Student
{
public int Id { get; set; }
}

第3行就是我们的自动属性了,其写法就是在属性后加{ get; set; }。省了私有变量和访问器的定义,一行就搞定,但其功能还是和以前的属性一模一样。这就是自动属性的好处。但是自动属性不能实现前面提到过的对输入输出做特殊处理。

另外,想要把一个属性变为只读的,用自动属性可以这样写:

 class Student
{
public Student(int id)
{
Id = id;
}
public int Id { get; private set; }
}

上面代码中第7行在set访问器前面加上private,属性赋值没办法被外部调用,自然是变成只读属性了。但在第3-6行要记得加入构造函数给属性赋初值。这个类的调用方法如下:

 Student student = new Student();
Console.Write(student.Id);

第1行用构造函数给Id赋值,第2行获取所赋的值。结果如下:

[C#详解] (1) 自动属性、初始化器、扩展方法

点我看自动属性

初始化器

初始化器分为对象初始化器和集合初始化器。下面一一介绍。

对象初始化器

对象初始化器的作用,简单点说就是可以使我们初始化一个类的代码变得更简洁。比如下面这个类:

class Person
{
public string Name { get; set; }
public int Age { get; set; }
public string Address { get; set; }
}

我们要初始化它并对它赋值的话通常要这样:

Person person = new Person();
person.Name = "Slark";
person.Age = ;
person.Address = "Xi'an";

这里我们用了一行创建对象语句,加三行赋值语句。这里光person这个变量就出现了4遍,繁琐。用对象初始化器来代替这些操作:

Person person = new Person { Name = "Slark", Age = , Address = "Xi'an" };

同样的效果,对象初始化器只用了一行,简洁!可以看到对象初始化器将创建对象和赋值合为一行,其中赋值就是在后面大括号里做的。这里的赋值可以给所有属性赋值,也可以给部分属性赋值。

集合初始化器

既然要讲集合初始化器,那么我们就先来创建一个集合:

List<int> intList = new List<int>();
intList.Add();
intList.Add();
intList.Add();

好,这里我们用4行代码创建了一个3个元素的集合。集合初始化器的出现大大减少了我们对这种操作的代码量。其对应的集合初始化器代码为:

List<int> intList = new List<int> { , ,  };

嗯,真的少写了很多。集合初始化器的原理也很简单,就是它默默的为我们调用了List的Add方法依次为我们添加了这3个元素。

这里我们再给一个综合运用集合初始化器和对象初始化器的例子:

List<Person> personList = new List<Person>
{
new Person { Name = "Slark1", Age = , Address = "Xi'an1" },
new Person { Name = "Slark2", Age = , Address = "Xi'an2" },
new Person { Name = "Slark3", Age = , Address = "Xi'an3" }
};

代码里用集合初始化器初始化了personList,然后用对象初始化器初始化了3个Person对象实例。这其中省了多少代码,真是不谈了。

点我看初始化器应用实例

扩展方法

扩展方法,简单点说就是可以在不改变现有类的情况下给这个类添加方法。我觉得扩展方法的最大意义在于我们可以给那些我们根本无法修改的类,比如String,添加我们自定义的方法。既然无法通过修改来添加,那就只能通过扩展了。

这让我想到了开闭原则(Open-Close Principle,OCP):一个软件实体应该对扩展开放,对修改关闭。

既然类对扩展开放了,我们就赶紧来试试吧!

无参数扩展方法

先试着给String添加一个DoubleString方法,就是把这个字符串输出两遍。

先创建一个静态类StringExtension:

 static class StringExtension
{
public static string DoubleString(this string str)
{
return str + str;
}
7 }

注意第1行,我们把要扩展的方法放在一个类里,并且这个类必须是静态类,要加static。类的名字随便起,无所谓。第3-6行就是我们想要扩展的方法。这个方法比较特殊,在定义的时候要写成静态方法,但是在调用的时候要当实例方法用。这个方法的参数写成this string str 表示要把这个方法加到String类中。但是这个方法在调用时是不能加参数的。

调用方法如下:

string str = "ABCD";
Console.Write(str.DoubleString());

可以看到,扩展的方法DoubleString被调用的时候被当作实例方法,并且没有参数。运行结果如下:

[C#详解] (1) 自动属性、初始化器、扩展方法

结果符合我们的预期。

带参数扩展方法

如果要给扩展方法带参数怎么办?示例代码如下:

 static class StringExtension
{
public static string RepeatString(this string str, int row,int column)
{
string s = string.Empty;
for (int i = ; i < row; i++) {
for (int j = ; j < column; j++)
{
s += str + " ";
}
s += "\r\n";
}
return s;
}
}

注意第3行这里一共有3个参数,其中后两个参数会在调用这个扩展函数的时候被赋值,这里这个RepeatString函数会把一个字符串写成几行几列的矩阵。

调用方法如下:

string str = "ABCD";
Console.Write(str.RepeatString(,));

调用时的第一个参数对应定义时的第二个参数,调用时的第二个参数对应定义时的第三个参数。显示结果如下。

[C#详解] (1) 自动属性、初始化器、扩展方法

点我看扩展方法实例

结尾

呼呼~ 终于写完了,腰酸背痛腿抽筋。

喜欢就推荐下吧!

作者:Slark.NET

出处:http://www.cnblogs.com/slark/

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。如有问题或建议,请多多赐教,非常感谢。

[C#详解] (1) 自动属性、初始化器、扩展方法的更多相关文章

  1. 【three&period;js详解之二】渲染器篇

    [three.js详解之二]渲染器篇   本篇文章将详细讲解three.js中渲染器(renderer)的设置方法. three.js文档中渲染器的分支如下: Renderers CanvasRend ...

  2. 详解android&colon;scaleType属性

    详解android:scaleType属性 转自:http://blog.csdn.net/encienqi/article/details/7913262    http://juliaailse. ...

  3. javaCV开发详解之2:推流器实现,推本地摄像头视频到流媒体服务器以及摄像头录制视频功能实现&lpar;基于javaCV-FFMPEG、javaCV-openCV&rpar;

    javaCV系列文章: javacv开发详解之1:调用本机摄像头视频 javaCV开发详解之2:推流器实现,推本地摄像头视频到流媒体服务器以及摄像头录制视频功能实现(基于javaCV-FFMPEG.j ...

  4. 详解CSS float属性(转)

    详解CSS float属性   阅读目录 基础知识 float的详细细节 float特殊情况 clear属性 清除浮动 float的应用 总结 CSS中的float属性是一个频繁用到的属性,对于初学者 ...

  5. 深入解析ThreadLocal 详解、实现原理、使用场景方法以及内存泄漏防范 多线程中篇(十七)

    简介 从名称看,ThreadLocal 也就是thread和local的组合,也就是一个thread有一个local的变量副本 ThreadLocal提供了线程的本地副本,也就是说每个线程将会拥有一个 ...

  6. ios学习--详解IPhone动画效果类型及实现方法

    详解IPhone动画效果类型及实现方法是本文要介绍的内容,主要介绍了iphone中动画的实现方法,不多说,我们一起来看内容. 实现iphone漂亮的动画效果主要有两种方法,一种是UIView层面的,一 ...

  7. JVM类加载机制详解(二)类加载器与双亲委派模型

    在上一篇JVM类加载机制详解(一)JVM类加载过程中说到,类加载机制的第一个阶段加载做的工作有: 1.通过一个类的全限定名(包名与类名)来获取定义此类的二进制字节流(Class文件).而获取的方式,可 ...

  8. 详解CSS float属性

    CSS中的float属性是一个频繁用到的属性,对于初学者来说,如果没有理解好浮动的意义和表现出来的特性,在使用的使用很容易陷入困惑,云里雾里,搞不清楚状态.本文将从最基本的知识开始说起,谈谈关于浮动的 ...

  9. css详解background八大属性及其含义

    background(背景) 以前笔者在css盒模型以及如何计算盒子的宽度一文中提到过盒模型可以看成由 元素外边距(margin).元素边框(border).元素内边距(padding)和元素内容(c ...

随机推荐

  1. 由360手机卫士谈起——让你的service获取最高权限。

    近日来,我在倒腾360手机卫士的时候,发现,你无论是把他数据清空,还是把它强行停止以后,甚至是把它卸载以后,它的service都没有被Android的系统干掉,依然是岿然不动了.我就感到了纳闷了,后来 ...

  2. 查看现有运行的linux服务器有多少内存条

    i161 admin # ssh 192.168.5.209 dmidecode | grep 'Ending Address' -B1 -A2    Starting Address: 0x0000 ...

  3. Android入门之GridView(表格控件)

    GridView是一个表格控件,可以在每个单元格中显示自定义的View或者字符串.在这里我们要实现一个图标下方有文字的效果. 1.首先我们应自定义布局文件image_text.xml.代码如下: &l ...

  4. http协议要点

    概念: HTTP是Hyper Text Transfer Protocol(超文本传输协议)的缩写.它的发展是万维网协会(World Wide Web Consortium)和Internet工作小组 ...

  5. Java基础05 实施接口

    作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 在封装与接口中,private关键字封装了对象的内部成员.经过封装,产品隐藏了内部 ...

  6. java设计模式之九外观模式(Facade)

    外观模式是为了解决类与类之家的依赖关系的,像spring一样,可以将类和类之间的关系配置到配置文件中,而外观模式就是将他们的关系放在一个Facade类中,降低了类类之间的耦合度,该模式中没有涉及到接口 ...

  7. WebApi使用cors配置跨域问题

    1.首先安装CORS,在WebApiCors项目上面使用Nuget搜索“microsoft.aspnet.webapi.cors”,安装第一个 2.当我们安装这个包之后,现有的packages目录下会 ...

  8. 构建你的spring boot代码

    Spring boot不需要任何特定的代码布局来工作.然而,有一些最佳实践可以帮助您. 1.避免使用缺省包 当一个类不包含包声明时,它被认为是在“缺省包”中.“默认包”的使用通常是不鼓励的,应该避免. ...

  9. datatime

    /把一个日期字符串如“2007-2-28 10:18:30”转换为Date对象 var   strArray=str.split("   "); var   strDate=str ...

  10. jni&amp&semi;&amp&semi;jvmti&amp&semi;&amp&semi;JMC

    jni&&jvmti http://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html htt ...