文章出處

今天在進行代碼測試時發現,嘗試在一個方法中定義一個委托,注意是定義一個委托,而不是聲明一個委托變量,在編寫的時候沒有報錯,VS也能智能提示,但在編譯時卻報語法不完整,缺少方括號,但實際查詢并沒有缺少,想不通原因,將委托定義移到類中,報錯消失,編譯成功了。

先看一下報錯的源碼:(實際上不只委托類型,所有的自定義類型均報錯)

    class Class2
    {
        public void Test()
        {
             delegate void testDel(string p); //是錯誤的

             event testDel testEvnt;//testDel無法生效,所以這里是錯誤的

            struct teststruct //是錯誤的
            {
                public string TName
                {get;set;}
            };

             teststruct tStruct=new teststruct();  //teststruct無法生效,所以這里是錯誤的

            class testClass //是錯誤的
            {
                public string TTT
                {get;set;}
            };

            testClass tClass=new testClass(); //testClass無法生效,所以這里是錯誤的

            enum testenum //是錯誤的
            {
                A,
                B,
                C
            };

             testenum TEnum=testenum.A; //testenum無法生效,所以這里是錯誤的
        }
    }

報錯的截圖如下:

將這些類型移到類中定義,編譯就成功,截圖如下:

    class Class2
    {
        delegate void testDel(string p);

        struct teststruct
        {
            public string TName
            { get; set; }
        };

        class testClass
        {
            public string TTT
            { get; set; }
        };

        enum testenum
        {
            A,
            B,
            C
        };

        event testDel testEvnt;
        public void Test()
        {

            teststruct tStruct = new teststruct();

            testClass tClass = new testClass();

            testenum TEnum = testenum.A;
        }
    }

在沒有合理的解釋下,唯有C#語法不允許這個理由還起來算合理,但若要問為什么不可以,請教多人卻沒有人能真正解答根本原因。

其實還是讓人不理解,匿名類型為什么能直接聲明,而自定義的類型就不行了呢? 難道說MS使用匿名類型就是為了彌補不能局部定義自定義類型,從編程的角度講,局部定義自定義類型應該是合理的,我想其原因可能與程序集有關,因為C#的所有類型必須顯示定義在程序集下(除了匿名類型),而如果是放在方法中程序集就無法直接找到該類型的完整路徑。
以下是VS智能提示的在方法中自定義類型的程序集完整路徑:

從編譯器智能提示的程序集路徑為 命名空間.類名.自定義類型名,而在方法中的實際路徑應該為(我理解):命名空間.類名.方法簽名.自定義類型名,兩者匹配不到,所以報錯。

同樣的編程思想(即在方法中定義自定義類型)在Javascript中卻是可,以下是JS代碼:

<html doctype>
<head>
    <title>Test</title>
</head>
<body>
    <script type="text/javascript">

        function Person(name) {
            this.Name = name;
            this.Say = function (age) {
                function Address(shen, shi, xian) { //定義Address類型的構造函數
                    this.Shen = shen;
                    this.Shi = shi;
                    this.Xian = xian;
                    this.GetFullAddress = function () {
                        return this.Shen + this.Shi + this.Xian;
                    };
                };

                var Addr = new Address("湖北省", "黃岡市", "XX縣");//實例化一個Address類型
                alert("我叫" + this.Name + ",今年" + age + "歲!\n 來自:" + Addr.GetFullAddress());
            }
        }

        var P = new Person("zuowenjun");
        P.Say(29);

    </script>
</body>
</html>

運行的結果:

我在想JS都支持,C#語言為什么不支持,不支持總有它的理由吧?除了我上述分析的是因為類型程序集路徑不正確導致,目前真沒有合理的理由了,若者從報錯的角度來說,是否是我的編寫語法不對,如果局部定義不是這樣,那又是怎樣的呢?還請大家幫忙分析一下,指點迷津,非常感謝!

看到大家對我這篇博文貶聲較多, 我在此補充說明一下,之所以我會有這樣的思考,是基于C#的匿名類型、嵌套類型、動態類型的特性以及JS的偽類型的一種設想,其實我的初衷設想是:在方法體內需要使用某種類型,但這個類型又只需在局部可反復使用,就應該存在一種局部類型,或者稱為臨時類型,這種類型的與匿名類型類似,但又有不同,不同是匿名類型一旦實例化就不可變更,而這種局部類型是與普通類型相同,只是作用域在方法體中,雖然可以使用元組Tuple及動態類型ExpandoObject實現類似功能,但畢竟在使用時不夠直觀。不論JS是高級還是低級,至少它是支持這種思想的。


文章列表


不含病毒。www.avast.com
arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()