给 c# 程序员的十个重要提示

目录
  • 1: 为非公开的方法编写测试
  • 2: 使用 Tuples 类型
  • 3: 用 yield 替代临时集合
  • 4: 告诉别人你将替换一个方法
  • 5: 牢记 LINQ 查询是延迟执行的
  • 6: 使用 explicit 关键字转换业务实体类型
  • 7: 保持异常的原始堆栈跟踪
  • 8: 使用 Flags 标记将枚举作为位域处理
  • 9: 为泛型添加类型约束
  • 10: IEnumerable 类型不能确保只读

本文讲述我认为对 c# 程序员最重要的 10 个提示, 每个提示都会有一段对应的代码, 对 新手来说也很容易掌握。

1: 为非公开的方法编写测试

你尝试过为组件的非公开方法写测试么? 很多开发者都没有写过, 因为这些方法对测试项 目来说是不可见的。 c# 可以通过在 AssemblyInfo.cs 中添加下面的标记 (InternalsVisibleToAttribute) , 让内部成员对其它组件可见。

//Make the internals visible to the test assembly
[assembly: InternalsVisibleTo("MyTestAssembly")]

2: 使用 Tuples 类型

曾经见到过有人仅仅因为函数要返回多个值而创建了一个 POCO 类, 其实 .Net 4.0 中的 Tuples 类型会更加适用, 例如:

public Tuple<int, string, string> GetEmployee() {
 int employeeId = 1001;
 string firstName = "Rudy";
 string lastName = "Koertson";

 //Create a tuple and return
 return Tuple.Create(employeeId, firstName, lastName);
}

3: 用 yield 替代临时集合

从集合中选出部分成员时, 通常会创建一个临时集合/列表来保存成员并返回, 例如下面 的代码:

public List<int> GetValuesGreaterThan100(List<int> masterCollection) {
 List<int> tempResult = new List<int>();

 foreach (var value in masterCollection) {
  if (value > 100) {
   tempResult.Add(value);
  }
 }
 return tempResult;
}

要避免这样的临时集合, 可以使用 yield 关键字, 示例如下:

public IEnumerable<int> GetValuesGreaterThan100(List<int> masterCollection) {
 foreach (var value in masterCollection) {
  if (value > 100) {
   yield return value;
  }
 }
}

当然, 也可是使用 LINQ 来解决上面的问题。

4: 告诉别人你将替换一个方法

当你有一个组件时, 并且你打算替换其中的一个方法时, 可以先为方法添加过时标记以通 知客户端, 示例代码如下:

[Obsolete("This method will be deprecated soon. You could use XYZ alternatively.")]
public void MyComponentLegacyMethod() {
 //Here is the implementation
}

使用这个方法客户端在编译时会发出一个警告, 如果你不再允许客户端使用过时的方法时, 可以为过时标记添加一个额外的布尔参数, 在下面的例子中, 客户但程序将编译失败:

[Obsolete("This method is deprecated. You could use XYZ alternatively.", true)]
public void MyComponentLegacyMethod() {
 //Here is the implementation
}

5: 牢记 LINQ 查询是延迟执行的

在 .NET 中编写 LINQ 查询时, 只有当你访问 LINQ 查询的结果时, LINQ 查询才会被执 行, LINQ 的这种特征被称为延迟执行, 不过值得注意的是每访问一次结果, LINQ 查询 都会被执行一次。

为了避免重复 LINQ 查询的重复执行, 可以先将查询转换成列表, 如下所示:

public void MyComponentLegacyMethod(List<int> masterCollection) {
 // 在下面示例中, 如果没有调用 ToList , LINQ 查询将会被执行两次
 var result = masterCollection.Where(i => i > 100).ToList();
 Console.WriteLine(result.Count());
 Console.WriteLine(result.Average());
}

6: 使用 explicit 关键字转换业务实体类型

使用 explicit 关键字来定义业务实体类型之间的转换, 当代码中出现类型转换请求时, 转换方法会自动执行, 下面是示例代码:

class Program {

 static void Main(string[] args) {
  var entity = new ExternalEntity {
   Id = 1001,
   FirstName = "Dave",
   LastName = "Johnson"
  };
  var convertedEntity = (MyEntity)entity;
 }
}

class MyEntity {

 public int Id { get; set; }
 public string FullName { get; set; }

 public static explicit operator MyEntity(ExternalEntity externalEntity) {
  return new MyEntity {
   Id = externalEntity.Id,
   FullName = externalEntity.FirstName + " " + externalEntity.LastName
  };
 }
}

class ExternalEntity {
 public int Id { get; set; }
 public string FirstName { get; set; }
 public string LastName { get; set; }
}

7: 保持异常的原始堆栈跟踪

在 c# 代码中, 如果你像下面的代码一样在 catch 代码块中抛出 ConnectDatabase 方法中出现的异常, 异常的堆栈就会只显示到 RunDataOperation 方法, 这样就会丢失 异常原始的堆栈跟踪信息导致不能找到确切的错误源头。

public void RunDataOperation() {
 try {
  Intialize();
  ConnectDatabase();
  Execute();
 }
 catch (Exception exception) {
  throw exception;
 }
}

保持原始堆栈跟踪的代码如下:

public void RunDataOperation() {
 try {
  Intialize();
  ConnectDatabase();
  Execute();
 }
 catch (Exception) {
  throw;
 }
}

8: 使用 Flags 标记将枚举作为位域处理

在 c# 中为枚举类型添加 Flags 标记可以将枚举作为位域(即一组标志)处理, 这样可 以对枚举值进行自由组合, 示例代码如下:

class Program {
 static void Main(string[] args) {
  int snakes = 14;
  Console.WriteLine((Reptile)snakes);
 }
}

[Flags]
enum Reptile {
 BlackMamba = 2,
 CottonMouth = 4,
 Wiper = 8,
 Crocodile = 16,
 Aligator = 32
}

上面代码的输出为 “BlackMamba, CottonMouth, Wiper” , 如果没有 Flags 标记, 则上 面的输出为 14 。

9: 为泛型添加类型约束

创建泛型类型时, 需要指定提供的泛型类型必须实现指定的参数或者继承自特定的基类时, 可以这样做:

class MyGenricClass<T> where T : IMyInterface {
 //Body of the class come in here
}

当然, 也可以在方法级别这样做:

class MyGenricClass {

 public void MyGenericMethod<T>(T t) where T : IMyInterface {
  //Generic implementation goes in here
 }

}

10: IEnumerable 类型不能确保只读

在你创建的类型中, 暴露了一个类型为 IEnumerable 的只读属性, 但是调用者依然可 以通过类型转换来修改属性的内容, 比如这样:

class Program {

 static void Main(string[] args) {
  MyClass myClass = new MyClass();
  ((List<string>)myClass.ReadOnlyNameCollection).Add("######From Client#####");

  myClass.Print();
 }
}

class MyClass {

 List<string> _nameCollection = new List<string>();

 public MyClass() {
  _nameCollection.Add("Rob");
  _nameCollection.Add("John");
  _nameCollection.Add("Jummy");
  _nameCollection.Add("Derek");
 }

 public IEnumerable<string> ReadOnlyNameCollection {
  get { return _nameCollection.AsEnumerable(); }
 }

 public void Print() {
  foreach (var item in ReadOnlyNameCollection) {
   Console.WriteLine(item);
  }
 }
}

上面的代码修改了列表, 添加了一个新项目, 要避免这种情况, 应使用 AsReadOnly 而不是 AsEnumerable :

public IEnumerable<string> ReadOnlyNameCollection {
 get { return _nameCollection.AsReadOnly(); }
}

以上就是给 c# 程序员的十个重要提示的详细内容,更多关于c# 程序员的十个重要提示的资料请关注我们其它相关文章!

(0)

相关推荐

  • C#中TextBox实现输入提示功能的方法

    本文实例讲述了C#中TextBox实现输入提示功能的方法.分享给大家供大家参考.具体如下: 设置TextBox的AutoCompleteSource的属性为CustomSource,设置TextBox的AutoCompleteMode属性为SuggestAppend. using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawin

  • C#程序提示“正由另一进程使用,因此该进程无法访问该文件”的解决办法

    问题描述: 图片加载后显示,然后进行删除操作时提示"--正由另一进程使用,因此该进程无法访问该文件.--" 解决办法: 原代码: 复制代码 代码如下: iml.Images.Add(Image.FromFile(potopath + "\\" + fi.Name)); 改为: 复制代码 代码如下: Image img = Image.FromFile(potopath + "\\" + fi.Name);  iml.Images.Add(img)

  • C#实现倒计时关闭提示框功能

    前两天实现某个功能需要做一个提示框 并且能够自动关闭的,就从网上搜了一个能够自动关闭的提示框 ,但由于我需要的场景是不确定计时时间的,所以并没有使用到该窗体,但是我觉得可以留存备用 ,后边也把我这种倒计时的提示框用处还是很多的,用于自动弹窗 自动关闭 ,虽然在我的项目中没有 其核心方法在 timer(TimerCallBack,Object,int32,int32) TimerCallBack 是一个委托 ,代表要执行的方法,其用途可以用在各个定时去调用方法的场景,而且可以设置窗体的FormBo

  • C#浏览器提示跨域问题解决方案

    一,我们使用两个域名互相访问的时候会提示跨域,原因在哪里呢?如下图跨域,我们探究下 是什么原因导致浏览器报这个错呢? 二,我们研究下看看请求是否成功.,如下图,浏览器返回的是200,证明请求是成功了,同时返回是成功了,那为什么还提示跨域呢? 三,经过看浏览器跨域的提示可知道"No 'Access-Control-Allow-Origin' header is present on the requested resource",我们是返回的head缺少了允许的域名,这个是浏览器自己的检

  • 解决C#调用dll提示

    程序在32位操作系统上运行正常,在64位操作系统上运行读卡功能提示"试图加载格式不正确". ---------------------------------------------------------------------------- 点击项目属性,把目标平台Any CPU 设置为X86 以上这篇解决C#调用dll提示"试图加载格式不正确的程序"问题就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我们. 您可能感兴趣的文章: C#中

  • c#消息提示框messagebox的详解及使用

    C#消息提示框messagebox的详解及使用 消息对话框是用messagebox对象的show方法显示的.MessageBox对象是命名空间System.Windows.Forms的一部分,Show是一个静态方法,意思是说,不需要基于MessageBox类的对象创建实例,就可以使用该方法.而且该方法是可以重载的,即方法可以有不同的参数列表形式. 返回结果:DialogResult dr1=MessageBox.Show(text,caption,buttons,icon,defaultbutt

  • C#实现简单的loading提示控件实例代码

    自己画一个转圈圈的控件 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Drawing.Drawing2D; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows

  • c# 设置TeeChart控件的提示文本

    使用第三方Steema的TeeChart控件,设置鼠标放在某一线条点上,显示某一点的数据标签问题(虚线型十字光标基准线,放在线上显示对应点的二维坐标轴数据数据),调用InitTeeChartTipTools方法即可: /// <summary> /// TeeChart线条的指示工具 /// </summary> Steema.TeeChart.Tools.CursorTool cursorTool; /// <summary> /// 鼠标指示显示的文本 /// &l

  • C#实现状态栏提示信息功能的示例

    本功能是在winform平台上实现的,其他平台大同小异,不多做介绍. 1.首先创建一个测试用winform窗体 2.在winform窗体上添加一个notifyIcon控件 然后设置notifyIcon属性,可自行修改其name属性,本文中name属性为notifyIcon1,注意此时点击查看ContextMenuStrip属性时显示的是无,所以我们还需要添加一个ContextMenuStrip控件 此时再去查看notifyIcon1中的ContextMenuStrip的属性时发现里面会有新添加的

  • c# 关闭窗体时提示的小例子

    复制代码 代码如下: private void WorkflowConfigure_FormClosing(object sender, FormClosingEventArgs e)        { DialogResult result = MessageBox.Show("此操作会丢弃您的当前设置,确定要继续?", "退出", MessageBoxButtons.YesNo, MessageBoxIcon.Question); if (DialogResul

  • C#提示:“在证书存储区中找不到清单签名证书”的解决方法

    本文实例讲述了C#提示:"在证书存储区中找不到清单签名证书"的解决方法.分享给大家供大家参考.具体分析如下: 一.问题: 程序重新生成,提示错误:在证书存储区中找不到清单签名证书. 二.解决方法: 可能是之前部署的程序证书被我删掉了或是证书过期了,结果出现这个问题.解决方案如下: 方案1:右击项目属性->签名->为ClickOnce清单签名,将勾掉的选项去掉. 方案2:在签名中创建一个新的签名. 方案3:记事本打开相应的csproj文件,调整节点值.<SignMani

  • C# winForm实现的气泡提示窗口功能示例

    本文实例讲述了C# winForm实现的气泡提示窗口功能.分享给大家供大家参考,具体如下: using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; namespace WindowsFormsApplication60 { p

随机推荐