分享
 
 
 

C#编译器是如何判定某个变量没有使用过的?

王朝学院·作者佚名  2009-12-15
窄屏简体版  字體: |||超大  

这是我们某个组员在编程过程中提出的疑问。因为这个编译错误很容易避免,所以我一直也没有仔细想过这个问题,直到看过他的代码后才意识到,此问题并不是那么简单的。

先看看这段代码:

代码

class Program

{

static void Main(string[] args)

{

byte[] buf = new byte[1024];

T t = new T();

string str = "1234";

int n = 1234;

int? nn = 1234;

DateTime dt = DateTime.Now;

object o = 1234;

Console.WriteLine("finish");

}

}

class T { }

你觉得这段代码里有几个变量没有使用过呢?

如果从程序员的角度来看,答案应该是所有变量都没有使用过。但编译器给出的结果却有点违反直觉:

变量“str”已赋值,但其值从未使用过

变量“n”已赋值,但其值从未使用过

变量“nn”已赋值,但其值从未使用过

奇怪的地方在于,虽然所有变量都是用同样的方式声明,但编译器却只认为其中一部分没有使用过。这是怎么回事呢?

我们一个一个来分析。首先看看数组,如果使用默认值的话,编译器给出的信息就不同了:

byte[] buf1 = null; // 有警告

byte[] buf2 = new byte[1024]; // 没有警告

这个结果似乎表明,如果参数赋值为null,那么编译器并不会真的执行赋值,并且变量会当作没有使用过。用IL检查的结果也可以证明此说法:对第一行,编译器没有生成任何对应的语句;对第二条则使用了newattr指令来创建数组。

对于自定义的类:

T t1 = null; // 有警告

T t2 = new T(); // 没有警告

这个结果应当是可以理解的(尽管可以理解,但我认为并不好,理由见后)。虽然我们并没有调用该类的任何方法,但是类的构造函数仍然可能执行某些操作,所以只要创建了一个类,编译器就会把它当作已经使用过的。

对于基本值类型,其表现和引用类型又有所不同,编译器并不把初始赋值当作对变量的使用:

int n1 = 0; // 有警告

int n2 = 1234; // 有警告

int? n3 = null; // 有警告

int? n4 = 0; // 有警告

int? n5 = 1234; // 有警告

string从实现上来说应当算是引用类型,但表现上却更加类似于值类型,警告信息也和值类型相同。

对于稍微复杂一些的值类型,结果有点微妙:

DateTime dt1; // 有警告

DateTime dt2 = new DateTime(); // 有警告

DateTime dt3 = new DateTime(2009,1,1); // 没有警告

DateTime dt4 = DateTime.Now; // 没有警告

这个结果有一点是需要注意的。尽管DateTime的默认构造函数和带参构造函数从用户角度看同样是构造函数,但在编译器的角度来看却是不一样的。用IL反编译也可以看出,如果调用默认构造函数的话,那么编译器调用的是initobj指令,而对带参构造函数调用的则是call ctor指令。此外,尽管从程序员的角度来看赋值代码的格式是完全相同的,但编译器却会根据所赋的值不同而采取不同的构造策略,这也是比较违反直觉的。

最后的结论比较遗憾,那就是C#的编译警告并不足以给予程序员足够的保护,特别是对于数组:

byte[] buf = new byte[1024];

如果仅构造这样一个数组而没有使用的话,那么编译器并不会给予程序员任何警告信息。

另外一个问题也是值得考虑的,声明一个类而不使用任何方法,比如仅仅

T t = new T()

这是合理的行为吗?编译器应该为此发出警告吗?

我个人的看法是,从使用的角度来说,这是不合理的,应当尽量避免,编译器发现此用法的话应该提出警告。如果确实有需要的话,可以通过编译指令或Attribute的方法来特别声明来避免警告信息。然而C#编译器的行为却是不发出警告,这一点我是不认同的。当然,我也希望大家提出自己的想法。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有