C#編譯器是如何判定某個變數沒有使用過的?

來源:互聯網
上載者:User
這是我們某個組員在編程過程中提出的疑問。因為這個編譯錯誤很容易避免,所以我一直也沒有仔細想過這個問題,直到看過他的代碼後才意識到,此問題並不是那麼簡單的。

先看看這段代碼:

代碼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#編譯器的行為卻是不發出警告,這一點我是不認同的。當然,我也希望大家提出自己的想法。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.