c# - 段小段查詢 - 雲林地號查詢




為什麼這段代碼不可達? (3)

C#規範說,

如果if語句可以訪問且布爾表達式沒有常量值false,則可以訪問if語句的第一個嵌入語句。

並且,關於常數表達式

常量表達式必須是null文字或具有以下類型之一的值:sbyte,byte,short,ushort,int,uint,long,ulong,char,float,double,decimal,bool,object,string或any枚舉類型。

在常量表達式中只允許以下構造:

  • 文字(包括null文字)。
  • 對類和結構類型的const成員的引用。
  • 引用枚舉類型的成員。
  • 對const參數或局部變量的引用
  • 帶括號的子表達式,它們本身是常量表達式。
  • 如果目標類型是上面列出的類型之一,則轉換錶達式。 選中和未選中的表達式
  • 默認值表達式
  • 預定義的+!~一元運算符。
  • 預定義的+*/%<<>>& ,|, ^&&||==!=<><=>=二元運算符,前提是每個操作數都是上面列出的類型。
  • ?:條件運算符。

成員訪問表達式不在此列表中,因此佈爾表達式不是常量。 因此if塊的主體是可達的。

我發現了一個案例,我有一些我認為無法訪問且未被檢測到的代碼。 編譯器和Visual Studio都不會發出警告。

考慮以下代碼:

enum Foo { A, B, C }
class Bar { public Foo type; }

static class Program
{
    private static void Main()
    {
        var bar = new Bar { type = Foo.A };

        if (bar.type == Foo.B)
        {
            Console.WriteLine("lol");
        }
    }
}

顯然,程序不會打印出“lol”,因為if語句中的條件為false。 我不明白為什麼沒有為無法訪問的代碼發出警告。 我唯一的假設是,如果你在多線程程序中遇到競爭條件,那麼這可能是可以達到的。 它是否正確?


因為在編譯時不能做出這樣的保證。 考慮這個替代Bar類

class Bar
{
   Random random = new Random();
   Array Foos = Enum.GetValues(typeof(Foo));

    private Foo _type;
    public Foo type
    {
        get { return _type; }
        set
        {
            _type = (Foo)Foos.GetValue(random.Next(3));
        }
    }
}

請注意,“可達”是在功能級別定義的。 即使在安全的情況下,也不允許到達正在測試的功能之外。


靜態分析只能做很多事情,如果能證明代碼無法更改,它只會將代碼標記為無法訪問。 在您的代碼中, Bar內部發生的事情超出了方法流程的範圍,無法進行靜態推理。 如果Bar的構造函數啟動一個將type值設置回B的線程怎麼辦? 編譯器無法知道它,因為Bar的內部結構也沒有作用於該方法。

如果您的代碼正在檢查局部變量的值,那麼編譯器可以知道它是否無法更改。 但事實並非如此。





unreachable-code