博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C# 编程的几个建议
阅读量:4496 次
发布时间:2019-06-08

本文共 3600 字,大约阅读时间需要 12 分钟。

1、属性(properties)

抽象属性可以放在接口的定义里。如:

public interface INameValuePair<T>
    {
        string Name { get; }
        T Value{ get; set; }
    }
所有私有字段的访问都建议使用属性来处理,类中所有的数据成员都应当是私有的。
属性在FCL(Framework类库)内部其实就是一个方法。
属性也可以是虚拟的(virtual),针对单独的get或set访问器可以有单独的访问修饰符。如:
public virtual string Name
    {
        get;
        protected set;
    }
JIT编译时使属性称为内联方法,所以速度和普通数据成员几乎一样.

属性里不要做冗长的计算或者跨应用的访问(如查询数据库).

2、偏爱readonly而不是const

C#有两种常量类型:编译时常量(用const声明)与运行时常量(用readonly声明)
编译时常量可以在方法内声明,而运行时常量不可以。
编译时常量只能是原子类型(内置整型、浮点型、枚举、string等),而运行时常量可以是任何类型。
最重要的是Readonly类型变量在运行时被解释,IL会生成对应对象的常引用 ,而const变量会被IL生成对应的值,而这样会对后期的维护造成不便。如下代码:
public class UsefulValues
{


  public static readonly int StartValue = 5;
  public const int EndValue = 10;
}
而在另一程序集,你引用了这些值:
for(int i = UsefulValues.StartValue;i<UsefulValues.EndValue; i++)
   Console.WriteLine("value is {0}", i);
然后经过一段事件你对原程序集进行了修改,修改后:
public class UsefulValues
{

  public static readonly int StartValue = 105;
  public const int EndValue = 120;
}
此时你希望输出是
value is 105
value is 106
...
value is 119
而实际将什么都不输出,因为此时的for循环已经是如下代码:
for(int i = UsefulValues.StartValue;i<10; i++)
   Console.WriteLine("value is {0}", i);
const变量会比readonly变量要稍微快一点,因为IL是直接为其生成常量字符串或数字,而readonly的灵活性要更好,因此我们应当偏爱readonly.

3、偏爱is和as而不是Cast

请使用as来进行两个对象之间的类型转换,(转换失败时返回null,不会引发异常)因为它更安全、更有效。

注意,as 运算符只执行引用转换和装箱转换,as 运算符无法执行其他转换。
as与is操作符不能执行任何的用户自定义类型转换,它从不自己构造新对象。而Cast则可实现类型转换,它会转换一个对象为请求的类型,如果转换一个高精度类型到低精度类型,则可能会丢失信息。
注意:as操作符不能用于值类型,值类型只能用Cast,而此时会产生装箱/拆箱操作,而此时一般建议会使用is操作符来先判断。如:
object o = Factory.GetValue();
int i = 0;
if(o is int)
  i=(int)o;
is操作符应该用在不能使用as操作符进行转换的时候。is检查对象是否与给定类型是否相同,返回true/false。
好的面向对象设计应当避免进行类型转换,但是有时你不得不进行类型转换的时候,使用as和is操作符可以更清晰地表达你的目的。

4、使用条件特性来代替#if

#if/#endif太容易滥用,创建的代码也很难理解和调试。C#增加了条件特性来指示一个方法是否应该被调用。它比#if/#endif更清晰。

#if/#endif方式:        private void CheckStateBad()        {            // The Old way:#if DEBUG            Trace.WriteLine("Entering CheckState for Person");            // Grab the name of the calling routine:            string methodName = new StackTrace().GetFrame(1).GetMethod().Name;            Debug.Assert(lastName != null, methodName, "Last Name cannot be null");            Debug.Assert(lastName.Length > 0, methodName, "Last Name cannot be blank");            Debug.Assert(firstName != null, methodName, "First Name cannot be null");            Debug.Assert(firstName.Length > 0, methodName, "First Name cannot be blank");            Trace.WriteLine("Exiting CheckState for Person");#endif        }

如果在Release模式编译生成,此方法将会是一个空方法。如果频繁地调用该方法也会产生一部分开销。而有时因为#if/#endif的位置不当,Release编译时会产生一些错误,

 

条件特性方式:
[Conditional("DEBUG")]

        private void CheckStateBad()
        {


...
}
该特性告诉编译器该方法只有在检测到有DEBUG环境变量时有效.
条件特性相比#if/#endif会生成更有效的IL代码.

5、C# null和" "的区别

String str1 = null;   str引用为空

String str2 = "";      str引用一个空串

也就是null没有分配空间,""分配了空间,因此str1还不是一个实例化的对象,而str2已经实例化

注意因为null不是对象,""是对象。所以比较的时候必须是 if(str1==null){...}和if(str2.equals("")){...}。

对象用equals比较,null用等号比较。因此,如果str1=null;下面的写法错误: 

if(str1.equals("")||str1==null)

{//如果str1没有值,则.... 

//。。。。 
正确的写法是 if(str1==null||str1.equals(""))

//先判断是不是对象,如果是,再判断是不是空字符串 

//... 
}

打个比方:一个空玻璃杯,你不能说它里面什么都没有,因为里面有空气,当然也可以把它弄成真空,null与" "的区别就象真空与空气一样。

6、C# 类型转换为int

Convert.ToInt32、int.Parse(Int32.Parse)、int.TryParse、(int) 四者都可以解释为将类型转换为 int,那它们的区别是什么呢?

  Convert.ToInt32 与 int.Parse 较为类似,实际上 Convert.ToInt32 内部调用了 int.Parse:
  Convert.ToInt32 参数为 null 时,返回 0; 参数为 "" 或者"  "时,抛出异常。Convert.ToInt32 可以转换的类型较多;
  int.Parse 参数为 null 时,抛出异常;参数为 "" 时,抛出异常。int.Parse 只能转换数字类型的字符串。
int.TryParse 与 int.Parse 又较为类似,但它不会产生异常,转换成功返回 true,转换失败返回 false。最后一个参数为输出值,如果转换失败,输出值为 0。
(int) 属 cast 转换,只能将其它数字类型转换成 int 类型,它不能转换字符串,否则报异常。

 

转载于:https://www.cnblogs.com/peterYong/p/6556712.html

你可能感兴趣的文章
VM虚拟机截图方法介绍
查看>>
servlet-定义+第一个sevlet程序
查看>>
SqlServer基础复习
查看>>
LeetCode【122. 买卖股票的最佳时机 II】
查看>>
label不换行的问题
查看>>
【日志】-2013.11.01
查看>>
Slimer软工课设日报-2016年7月5日
查看>>
【BZOJ 2138】stone
查看>>
【AGC028D】Chord
查看>>
线性筛法与积性函数
查看>>
欧拉路
查看>>
[USACO07FEB]Lilypad Pond
查看>>
第四周
查看>>
动态调用类中的方法
查看>>
查看类的声明
查看>>
Process、管理者权限、注册表、xml修改
查看>>
sqlserver with 递归用法
查看>>
关于跨域cookie,在代码无问题下,浏览器set-cookie显示有内容,但浏览器没写入cookie(刷新没有cookie)...
查看>>
.net core 中如何运用 appsettings.json 进行配置开发、生产不同配置
查看>>
.net core 中如何读取 appsettings.json 相关配置
查看>>