C#精益求精

目录

1.优先使用隐式类型的局部变量

2.考虑用readonly代替const

3.优先考虑is或as运算符,尽量少用强制类型转换

4.用内插字符串取代string.Format()

5.用FormattableString取代专门为特定区域而写的字符串

6.不要用表示符号名称的硬字符串来调用API

7.用委托表示回调

8.用null条件运算符调用事件处理程序

9.尽量避免装箱与拆箱

10.只有在应对新版基类与现有子类之间的冲突时才应该使用new修饰符



1.优先使用隐式类型的局部变量

用var来声明变量而不指明其类型,可以令开发者把注意力更多的集中在名称上。

var不是动态变量,而是编译器来根据右侧的类型推断。

2.考虑用readonly代替const

运行时的常量用readonly来声明,更为灵活。因为readonly是在执行构造函数后才不能被修改。类型不受限制,可以是随意的class

编译期的常量用const来声明(const可以在方法体内声明,readonly不行),常量是编译器把变量给替换成常量值,如果不同程序集都使用某个其他程序集的常量。而修改了常量值不编译其他程序集就会导致不一致。

3.优先考虑is或as运算符,尽量少用强制类型转换

强制类型转换有异常的情况,需要try/catch.而且要判断是不是等于Null

foreach内部使用的是强制类型转换,可能有历史包袱的原因。

比如

Int arr = {1,2,3,4};

foreacr (object I in arr)

是成立的。

as用于类型转换

is用于判断某个运行时类型是不是能转成目标类型,遵循多态规则。

4.用内插字符串取代string.Format()

String.Format()的不足

 int a=0, b = 0;

  string.Format("{1}{2}", a);

这种写法成立,由于有多个string.Format重载,编译器只会确定重载方法是否有合适的,不会检查参数个数与序号数量是否匹配。不匹配,就会抛出异常。

还有那种SQL语句的字符串拼接,可能有很多序号,需要一个一个的去核对序号是不是正确。容易出错。

内插字符串非常方便

String str =$"{var1}{var2}";

简短,不会出错

会把其他类型都转成string类型。

5.用FormattableString取代专门为特定区域而写的字符串

 内插字符串默认的类型是FormattableString,为了支持多区域和语言。

6.不要用表示符号名称的硬字符串来调用API

也就是不要直接硬编码某些参数。多使用nameof()可以返回字符串。这样后期修改不会因为大量硬编码导致漏改,增大重复工作量。

还有MVC中的Route

7.用委托表示回调

Action可以接收任意数量的参数,返回值为void

Func<T,T> 接收参数然后计算出返回值的委托,

predicate判断某条件是否成立的bool返回值委托,LINQ中很多

所有的委托都是继承自Multicastdelegate,都是多播委托。

有两个坑:

1.程序调用委托的过程中可能发生异常。

2.多播委托,如果有返回值,前面的返回值都被丢弃,最后一个执行委托的返回值被返回。

8.用null条件运算符调用事件处理程序

老版写法 if(variable !=null){}

如果变量是事件处理器,多线程的环境下,有可能其他线程正好取消事件订阅,而执行判断的线程被打断了。 非常坑

新版写法 variable?.Invoke(this,num);

可惜不能variable?();

9.尽量避免装箱与拆箱

尽量不要再使用object的地方使用值类型

2.

public struct Person

{

    public string Name { get; set; }

    public override string ToString()

    {

        return Name;

    }

}

public class Test

{

    public static void Main()

    {

        List<Person> attendees = new();

        Person p = new Person { Name = "Old Name" };

        attendees.Add(p);

        Person p2 = attendees[0];

        p2.Name = "New Name";

        Console.WriteLine(attendees[0].ToString());

    }

}

这段打印出Old Name

泛型未装箱,而取值的时候又是一份拷贝对象。

10.只有在应对新版基类与现有子类之间的冲突时才应该使用new修饰符

使用new关键字去覆盖基类的行为是不符合里氏替换原则的。但还是有特殊情况

比如说 继承的基类新加了方法,属性,而这新加的在原来的子类中有了,那么折中的做法就是new覆盖了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值