C#简单问题,不简单的原理:不能局部定义自定义类型(不含匿名类型)

今天在进行代码测试时发现,尝试在一个方法中定义一个委托,注意是定义一个委托,而不是声明一个委托变量,在编写的时候没有报错,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#语言为什么不支持,不支持总有它的理由吧?除了我上述分析的是因为类型程序集路径不正确导致,目前真没有合理的理由了,若者从报错的角度来说,是否是我的编写语法不对,如果局部定义不是这样,那又是怎样的呢?还请大家帮忙分析一下,指点迷津,非常感谢!

时间: 2024-08-24 19:57:44

C#简单问题,不简单的原理:不能局部定义自定义类型(不含匿名类型)的相关文章

匿名类型与Select方法实现自定义对象插入局部表结构中

在提取局部表结构数据时,通过Select选取需要的字段,如下句,此时其实产生了一个不用于_menuMan的原新数据类型new { c.SYS_COMMANDS_ID,c.TXT_COMMANDTITLE },这样的类型就叫匿名类型 var comdList = _menuMan.Load(c => c.FATHER_ID == null).OrderBy(c=>c.VAL_DISPLAYORDERID).Select(c=>new { c.SYS_COMMANDS_ID,c.TXT_CO

匿名内部类是一种特殊的局部内部类,它是通过匿名类实现接口

匿名内部类(必须掌握): 匿名内部类是一种特殊的局部内部类,它是通过匿名类实现接口. IA被定义为接口. IA I=new IA(){}; 注:一个匿名内部类一定是在new的后面,用其隐含实现一个接口或实现一个类,没有类名,根据多态,我们使用其父类名. 因其为局部内部类,那么局部内部类的所有限制都对其生效. 匿名内部类是唯一一种无构造方法类. 匿名内部类在编译的时候由系统自动起名Out$1.class. 如果一个对象编译时的类型是接口,那么其运行的类型为实现这个接口的类. 因匿名内部类无构造方法

C++11 局部和匿名类型作模板实参

[1]C++11支持局部的类型和匿名类型做模板的实参 在C++98中,标准对模板实参的类型还有一些限制. 具体地讲,局部的类型和匿名的类型在C++98中都不能做模板类的实参. 而在C++11标准中,支持做模板的实参.示例如下: 1 template<typename T> class X {}; 2 template<typename T> void TempFun(T t) {}; 3 4 struct A { } a; 5 struct { int i; } b; // b是匿

菜鸟学SSH(十五)——简单模拟Hibernate实现原理

之前写了Spring的实现原理,今天我们接着聊聊Hibernate的实现原理,这篇文章仅仅是简单的模拟一下Hibernate的原理,主要是模拟了一下Hibernate的Session类.好了,废话不多说,先看看我们的代码: package com.tgb.hibernate; import java.lang.reflect.Method; import java.sql.Connection; import java.sql.DriverManager; import java.sql.Pre

题海,原理,局部,整体——机械与思考

研究生的最后一门考试的科目已经画上了句号,考的是矩阵论. 人生有大大小小.形形色色.各种各样的考试,这或许只是其中微不足道的一部分. 但,自尊,已经被深深刺痛. 本科啃课本或许能啃出好成绩,但啃不出思维的变化,啃不出思考的方式. 自己俨然变成了机器人,没有思考,亦步亦趋,人云亦云. 思考在哪里?机械的思考? 这不是我想要的. 绝不是. 机械的方式绝不是创造力提升的方法,包括机械的思维. 就如同机械的刷矩阵论的题目,没有从原理上真正弄懂,结果只是自欺欺人. 但,我始终相信,一份付出,一份收获. 只

LC滤波器简单设计法 - 一文读懂LC滤波器简单设计方法及原理介绍,LC值计算方法

LC滤波器概述 LC滤波器也称为无源滤波器,是传统的谐波补偿装置.LC滤波器之所以称为无源滤波器,顾名思义,就是该装置不需要额外提供电源.LC滤波器一般是由滤波电容器.电抗器和电阻器适当组合而成,与谐波源并联,除起滤波作用外,还兼顾无功补偿的需要. LC滤波器是利用电感.电容和电阻的组合设计构成的滤波电路,可滤除某一次或多次谐波,最普通易于采用的无源滤波器结构是将电感与电容串联,可对主要次谐波(3.5.7)构成低阻抗旁路:单调谐滤波器.双调谐滤波器.高通滤波器都属于无源滤波器. LC滤波器的分类

使用C++实现一套简单的状态机模型——原理解析

在上一文中,我们介绍了该状态机模型的使用方法.通过例子,我们发现可以使用该模型快速构建满足基本业务需求的状态机.本文我们将解析该模型的基础代码,以便大家可以根据自己状态机特点进行修改.(转载请指明出于breaksoftware的csdn博客) 该模板库的基础方法实现在之后给出的工程的AutoStateChart.h中,该文件一共215行,其中有16行是辅助调试代码.以上一文中状态机类为例: class CMachine_Download_Run_App : public AutoStateCha

简单梳理memcached工作原理/工作流程/优化建议

一.memcached工作原理基本概念:slab,page,chunk.slab,是一个逻辑概念.它是在启动memcached实例的时候预处理好的,每个slab对应一个chunk size,也就是说不同slab有不同的chunk size.具体分配多少个slab由参数 -f (增长因子)和 -n (chunk最小尺寸)决定的.page,可以理解为内存页.大小固定为1m.slab会在存储请求时向系统申请page,并将page按chunk size进行切割.chunk,是保存用户数据的最小单位.用户

基于Redis的简单分布式锁的原理

参考资料:https://redis.io/commands/setnx 加锁是为了解决多线程的资源共享问题.Java中,单机环境的锁可以用synchronized和Lock,其他语言也都应该有自己的加锁机制.但是到了分布式环境,单机环境中的锁就没什么作用了,因为每个节点只能获取到自己机器内存中的锁,而无法获取到其他节点的锁状态. 分布式环境中,应该用专门的分布式锁来解决需要加锁的问题.分布式锁有很多实现,Redis,zookeeper都可以.这里以Redis为例,讲述一下基于Redis的分布式