### C#中的四个实用技巧详解 #### 技巧一:优先使用接口进行编程 在.NET框架中,提供了丰富的类和接口供开发人员使用。在实际编程过程中,虽然我们经常能够明确知道正在使用的具体.NET类,但若能尽可能地采用.NET框架支持的接口来进行编程,则能使代码更加稳定且具有更高的可用性。 **示例代码分析:** 原代码示例展示了通过对象数组填充ListBox的方法: ```csharp private void LoadList(object[] items, ListBox l) { for (int i = 0; i < items.Length; i++) l.Items.Add(items[i].ToString()); } ``` 这种方法存在局限性,因为它依赖于ListBox的具体实现。如果未来需要更改ListBox或使用其他控件,就需要修改代码。为了解决这个问题,可以改为使用`ICollection`接口来编写更加灵活的代码: ```csharp private void LoadList(ICollection items, ListBox l) { foreach (object o in items) l.Items.Add(o.ToString()); } ``` 在这个改进后的版本中,我们使用了`ICollection`接口而非具体的类型,这样做的好处在于,即使将来`items`变量的类型发生变化,只要它实现了`ICollection`接口,这段代码仍然可以正常工作,无需进行任何改动。此外,这也使得代码更加易于维护和扩展。 #### 技巧二:合理利用lazy evaluation思想 在某些场景下,我们可能希望某个属性只有在首次访问时才进行初始化,之后再访问时则直接返回已有的值。这被称为lazy evaluation(延迟计算)思想,有助于提高程序效率,尤其是在属性初始化成本较高时。 **示例代码分析:** 假设我们需要定义一个表示月份的属性,该属性在第一次被访问时才进行初始化,并将这个属性暴露给外部调用: ```csharp private int TheMonth = 0; [XmlAttribute("Month")] public int Month { get { return TheMonth; } set { TheMonth = value; } } ``` 这样的设计虽然简单,但在性能方面并不理想。更好的做法是利用lazy evaluation的思想,只有在首次访问时才进行实际的初始化操作: ```csharp private readonly Lazy<int> _monthLazy = new Lazy<int>(() => 0); [XmlAttribute("Month")] public int Month { get { return _monthLazy.Value; } set { _monthLazy = new Lazy<int>(() => value); } } ``` 这里使用了`Lazy<T>`类来实现延迟加载的功能,确保属性只在首次访问时执行初始化操作。 #### 技巧三:使用Producer/Consumer模式与委托 Producer/Consumer模式是一种常见的编程模式,它通常涉及到生产者和消费者两个角色。在C#中,我们可以利用委托(Delegate)来实现这一模式,从而实现生产者和消费者之间的解耦。 **示例代码分析:** 以下是一个简单的键盘输入处理器类,它定义了一个委托`OnGetLine`用于接收输入数据并进行处理: ```csharp public class KeyboardProcessor { private OnGetLine theFunc = null; public OnGetLine OnGetLineCallback { get { return theFunc; } set { theFunc = value; } } public void Run() { string s; do { s = Console.ReadLine(); if (s.Length == 0) break; if (theFunc != null) { System.Delegate[] funcs = theFunc.GetInvocationList(); foreach (OnGetLine f in funcs) { try { f(s); } catch (Exception e) { Console.WriteLine("Caught Exception: {0}", e.Message); } } } } while (true); } } ``` 在这个例子中,`KeyboardProcessor`类负责读取用户输入,并通过`OnGetLine`委托将数据传递给注册的消费者。这种方式不仅实现了生产者和消费者的解耦,还提高了代码的灵活性和可扩展性。 #### 技巧四:合理使用初始化器 在C#中,初始化器是一种非常实用的功能,它可以简化代码,让代码更加简洁明了。合理地使用初始化器,可以提高代码的可读性和可维护性。 **示例代码分析:** 假设我们有一个类`Person`,包含多个属性: ```csharp public class Person { public string Name { get; set; } public int Age { get; set; } public string Address { get; set; } } ``` 在创建实例时,可以直接使用初始化器进行赋值: ```csharp var person = new Person { Name = "张三", Age = 25, Address = "北京市" }; ``` 这种方式相比于逐一调用属性设置方法更加直观且简洁,尤其是在需要初始化多个属性时更为明显。此外,还可以使用集合初始化器来初始化集合类型的属性,如List、Dictionary等,使代码更加简洁高效。 以上四个技巧不仅可以帮助开发者编写出更高效、更稳定的代码,还能提升代码的可读性和可维护性。在日常开发中合理运用这些技巧,将能够显著提高开发效率和软件质量。
![application/x-rar](https://img-home.csdnimg.cn/images/20210720083606.png)
![zip](https://img-home.csdnimg.cn/images/20210720083736.png)
![application/x-rar](https://img-home.csdnimg.cn/images/20210720083606.png)
![application/x-rar](https://img-home.csdnimg.cn/images/20210720083606.png)
![application/x-rar](https://img-home.csdnimg.cn/images/20210720083606.png)
![application/x-rar](https://img-home.csdnimg.cn/images/20210720083606.png)
![application/octet-stream](https://img-home.csdnimg.cn/images/20210720083646.png)
![txt](https://img-home.csdnimg.cn/images/20210720083642.png)
![application/octet-stream](https://img-home.csdnimg.cn/images/20210720083646.png)
![application/octet-stream](https://img-home.csdnimg.cn/images/20210720083646.png)
![application/x-rar](https://img-home.csdnimg.cn/images/20210720083606.png)
![application/x-rar](https://img-home.csdnimg.cn/images/20210720083606.png)
![zip](https://img-home.csdnimg.cn/images/20210720083736.png)
![zip](https://img-home.csdnimg.cn/images/20210720083736.png)
![rar](https://img-home.csdnimg.cn/images/20210720083606.png)
![rar](https://img-home.csdnimg.cn/images/20210720083606.png)
![7z](https://img-home.csdnimg.cn/images/20210720083312.png)
1.如果可能尽量使用接口来编程
.NET框架包括类和接口,在编写程序的时候,你可能知道正在用.NET的哪个类。然而,在这种情况下如果你用.NET支持的接口而不是它的类来编程时,代码会变得更加稳定、可用性会更高。请分析下面的代码:
private void LoadList (object [] items, ListBox l)
{
for (int i = 0; i < items.Length;i++)
l.Items.Add (items[i].ToString ());
}
这个函数从一个可为任何对象的数组中加载ListBox,这段代码被限定为只能使用数组。假想过些时候你发现那些对象存在数据库中,或别的集合中。那么你需要修改程序来使用不同的集合类型。如果你用ICollection接口来写那段程序,你就不用修改那段程序了,对于任何实现ICollection接口的类型它都能很好的工作:
private void LoadList (ICollection items,ListBox l)
{
foreach (object o in items)
l.Items.Add (o.ToString ());
}
ICollection被数组和所有System.Collection中的集合实现。此外,多维数组也支持ICollection接口。如果那还不够的话,数据库.NET类同样支持ICollection接口。用接口写的这个函数不用需改就可以才许多中情况下使用。
2. 使用属性代替原始数据
因为属性已经成为语言本身的元素,所以声明数据元素时它的作用域等级没有必要大于private。因为代码本身会把属性看成数据元素,你并没有失去使用简单数据类型的便利性 。相反它会使你的代码更加灵活功能更加强大。属性使你的数据元素封装性更好。属性可以让你使用lazy evaluation来返回数据。lazy evaluation的意思是当用户请求时才计算它的值,而不是一直保留着它。
最后,属性可以是virtual也可以是abstract。你也可以在接口中定义属性。
这里还有维护方面的因素应当注意:尽管操作两者的方法是一样的,但是你把一个数据元素变成属性,那么原先客户端的程序便不能访问服务端的新版本程序了。实际上对于在Web service中你想实现序列化的值你可以把它们变成属性来使用:
private int TheMonth = 0;
![avatar-default](https://csdnimg.cn/release/downloadcmsfe/public/img/lazyLogo2.1882d7f4.png)
![avatar](https://profile-avatar.csdnimg.cn/default.jpg!1)
- 粉丝: 0
- 资源: 1
我的内容管理 展开
我的资源 快来上传第一个资源
我的收益
登录查看自己的收益我的积分 登录查看自己的积分
我的C币 登录后查看C币余额
我的收藏
我的下载
下载帮助
![voice](https://csdnimg.cn/release/downloadcmsfe/public/img/voice.245cc511.png)
![center-task](https://csdnimg.cn/release/downloadcmsfe/public/img/center-task.c2eda91a.png)
最新资源
- 基于Springboot和Vue的农商对接系统源码 农商对接系统代码(高分项目源码)
- Kubernetes-深入Pod(MD笔记)
- 数学建模-2021年-国赛D题-解决连铸切割问题(模拟训练专用)
- 基于Springboot的 农商对接系统源码 (优秀毕业设计源码)
- Python:kuw音乐歌词搜索获取工具
- RF时序预测RF时序预测RF时序预测RF时序预测
- 易航php加密平台源码2024首发
- python爬网第二课存储到记事本
- RBF时序预测RBF时序预测RBF时序预测
- 基于Springboot和Vue的大学生智能消费记账系统的设计与实现源码 大学生智能消费记账系统的设计与实现代码(高分项目源码)
![feedback](https://img-home.csdnimg.cn/images/20220527035711.png)
![feedback-tip](https://img-home.csdnimg.cn/images/20220527035111.png)
![dialog-icon](https://csdnimg.cn/release/downloadcmsfe/public/img/green-success.6a4acb44.png)