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

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(); }
}

希望这些提示对你有用!

原文地址: Top 10 Tips for C# Programmers

时间: 2024-10-13 12:05:28

给 c# 程序员的十个重要提示的相关文章

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

本文讲述我认为对 c# 程序员最重要的 10 个提示, 每个提示都会有一段对应的代码, 对 新手来说也很容易掌握. 1: 为非公开的方法编写测试 你尝试过为组件的非公开方法写测试么? 很多开发者都没有写过, 因为这些方法对测试项 目来说是不可见的. c# 可以通过在AssemblyInfo.cs 中添加下面的标记 (InternalsVisibleToAttribute) , 让内部成员对其它组件可见. //Make the internals visible to the test assem

优秀程序员的十个习惯

在这个世界上,有数百万的人热衷于软件开发,他们有很多名字,如:软件工程师(Software Engineer),程序员(Programmer),编码人(Coder),开发人员(Developer).经过一段时间后,这些人也许能够成为一个 优秀的编码人员,他们会非常熟悉如何用计算机语言来完成自己的工作.但是,如果你要成为一个优秀的程序员,你还可以需要有几件事你需要注意,如果你能让下 面十个条目成为你的习惯,那么你才能真正算得上是优秀程序员. 1. 学无止境 就算是你有了 10 年以上的程序员经历,

毁掉程序员的十个恶习

作为一个敢于追求潮流的人,并励志做到专业的帅哥,在学习前端的这段时间里发现了自己很 多的弯路,下面分享一下(供大神拍砖). 从学习web前端开始的1个半月的时间里,自己从一名刚开始的网络方面思考方式转到软件开发 人员敏捷的程序思考方式.成为一名软件开发人员不是那么的容易,尤其是自己在大学期间把 所有的精力都用在了网络方面,所以现在自己的软件方面的知识很少,思维也不够的灵活,但 这是缺点同时也是优点,大学教会了自己养成认真的习惯,努力肯学,同时也培养了自己的思 考能力,但我知道这些思考能力是远远不

程序员 需要 十个改变的

(1)程序员需要成长,就得需要放下一些东西,收敛一些东西. (2)一提到程序员,大家马上想到的就是其貌不扬,衣着不潮,目光呆滞,加班干点,朝五晚九的等等,正如外界的所尊称的"嫁就嫁程序员,钱多话少死的早!!!" (3)程序员的交际面很窄,在技术上鄙视一些使用computer的人员,记住程序员管电脑叫计算机,鄙视那些只会用鼠标点这点那的人,更可气的是它还鄙视它的同类(同行). (4)程序员脑子不笨,但是处理人情实物去总是碰壁,由于长时间和计算机打交道,对外界事物反应慢:脑子切换的比较慢,

转载-优秀程序员的十个tips

理解技术债务 技术债务就像信用卡一样,会有很高的利息,时间越长,修复所化的代价就越大.团队应该培养一种保证设计质量的文化,鼓励重构.同时应当鼓励其它有关代码质量的实践. 保持对原理的好奇心 做Android,了解一下事件分发机制,Measure/Layout,原生控件是怎么实现的 专注 程序员的工作效率可以差别很大,其中区别很大的一点就是专注,就像线程切换一样,恢复上下文有很大的代价.合理安排好时间,尽量在上午和下午留大块的专注时间来做设计和编程,可以尝试一下番茄工作法. 同理心 写代码时要有同

程序设计基石与实践系列之能让你成为Top程序员的十个C语言资源

英文出处:mycplus ---top-ten-c-language-resources 一些人觉得编程无聊,一些人觉得它很好玩.但每个程序员都必须紧跟编程语言的潮流.大多数程序员都是从C开始学习编程的,因为C是用来写操作系统.应用程序最常用的语言. C编程笔记 : 这些是华盛顿实验学院C编程入门课的部分笔记.它们是以<c程序设计语言>的补充笔记(从1995年春开始)为基础修改的,而这本书的作者就是大名鼎鼎的Brian Kernighan和Dennis Ritchie了,人们亲昵地称呼他们为K

程序员的十个层次,你属于哪一层?

自西方文艺复兴以来,中国在自然科学方面落后西方很多,软件领域也不例外.当然现在中国的许多程序员们对此可能有许多不同的意见,有些人认为中国的程序员水平远落后于西方,有些则认为中国的程序员个人能力并不比西方的程序员差,只是整个软件产业落后而已. 那么,到底中国的程序员水平比西方程序员水平差,还是中国有许多优秀的程序员达到或超过了西方程序员同等水平呢?要解决这个问题,必须先知道程序员有多少种技术层级,每个层级需要什么样的技术水平,然后再比较中国和西方在各个技术层级的人数,就可以知道到底有没有差距,差距

程序员的十个层次(转)

自西方文艺复兴以来,中国在自然科学方面落后西方很多,软件领域也不例外.当然现在中国的许多程序员们对此可能有许多不同的意见,有些人认为中国的程序员水平远落后于西方,有些则认为中国的程序员个人能力并不比西方的程序员差,只是整个软件产业落后而已. 那么,到底中国的程序员水平比西方程序员水平差,还是中国有许多优秀的程序员达到或超过了西方程序员同等水平呢?要解决这个问题,必须先知道程序员有多少种技术层级,每个层级需要什么样的技术水平,然后再比较中国和西方在各个技术层级的人数,就可以知道到底有没有差距,差距

程序员这十个java题你都会吗?

前言 不论你是职场新人还是步入职场N年的职场新人大哥大~当然这个N<3~,我能担保你答不对这十个题~不要问我为什么这么自信~,这些个题还是"有水平"的javase的基础题,传闻小白指定鸭蛋分,一测一个准,哈哈. 作为将来要成为架构师的男人,对,你没看错,就是在说你 ~皮一下很开森~ ,what?你是小白?我顶你个肺,我叫声杠精,你敢应吗,那个代号9527的杠精,说你呢快快来答题,看你能答对几道题. 题一 下面的程序有问题吗?如果有问题说明一下, 如果没有问题猜测一下运行结果 pu