列表与LT;>在不同的班级中有不同的行为

时间:2012-08-21 07:37:58

标签: c# .net list

我写了一个小代码,但发现了一些惊人的东西。我有一个班级名称学生和里面的calss声明了一个List<>像这样的变量名学生(与班级名称相同)

  Class Students
{
    private String Name;
    private int Age;   
    public Students(){}

    List<Students> Students = new List<Students>();

...
}

这里的编译时错误是

  

'学生':成员名称不能与其封闭类型相同

但是如果我在其他类中声明相同的List ......比如

        Class Students
        {
           private String Name;
           private int Age;   
           public Students(){}    
           ...
        }


        Class Program
        {
         ....
            List<Students> Students = new List<Students>();
            Students.Add(new Students("Deb","B++"));
            Students.Add(new Students("DDD", "A++"));
          ............
        }

这个工作正常。 我的问题是,为什么?我们如何在其他calsses中创建自定义变量作为类名,但不在同一个类中? 任何精心设计的答案都会很好,因为我想获得这方面的知识。

6 个答案:

答案 0 :(得分:7)

错误消息中提到了答案:

  

&#39;学生&#39;:会员姓名不能与他们的封闭类型

相同

如果您在与该成员同名的班级内,那只是一个错误。

无论如何,在任何情况下命名这样的变量都是一个坏主意。他们不应该被资本化。

修改:这是一个可能导致含糊不清的示例:

class A
{
    public void Foo() { }
}

class B
{
    private A B = new A();

    static void Foo() { }

    void Bar()
    {
        B.Foo(); // what am I calling here?
    }
}

编辑2 :稍微搜索一下,我发现了一个非常相似的问题:Why C# member names can't be the same as the enclosing type name?并且达成共识只是因为它是C#的限制(不清楚)解释原因)。 VB.NET似乎允许这种情况发生。

答案 1 :(得分:3)

你的班级被命名为学生,所以显然唯一被允许命名的成员是构造函数。

答案 2 :(得分:1)

在同一个班级中,无论你是在讲课还是在成员,这都是不明确的,而在另一个班级则不是。

此外,如果代表单个学生,您应该将课程命名为Student,即使学生列表听起来比学生列表更直观>。如果你持有一个参考文献,那看起来就错了。

答案 3 :(得分:1)

当你在类中声明它具有相同的名称时,编译器将如何确定它是一个类还是一个变量,但是当你在其他类中用它来声明它时,如下所示。

Program.Students

现在编译器可以看到两者之间的差异。

答案 4 :(得分:1)

class members上的C#语言规范文档与您的案例特别相关,它说:


类声明创建一个新的声明空间(第3.3节),类声明立即包含的类成员声明将新成员引入此声明空间。以下规则适用于类成员声明:

•实例构造函数,析构函数和静态构造函数必须与紧邻的类具有相同的名称。所有其他成员的名称必须与紧接着的类的名称不同。

•常量,字段,属性,事件或类型的名称必须与同一类中声明的所有其他成员的名称不同。

•方法的名称必须与同一类中声明的所有其他非方法的名称不同。此外,方法的签名(第3.6节)必须与同一类中声明的所有其他方法的签名不同。

•实例构造函数的签名必须与同一类中声明的所有其他实例构造函数的签名不同。

•索引器的签名必须与同一类中声明的所有其他索引器的签名不同。

•运算符的签名必须与同一类中声明的所有其他运算符的签名不同。


构造函数始终与类具有相同的名称,即使您未明确指定构造函数,也将存在默认构造函数。始终存在的构造函数基本上声明了该类成员名称的权限,因此不允许同样命名任何其他类成员(当然除了析构函数和静态构造函数的特殊情况)。

PS:VB对构造函数有不同的规则和命名,这就是上面不适用的原因。

答案 5 :(得分:1)

  

我们如何在其他calsses中创建自定义变量作为类名但不在同一个类中?

事实并非如此。您在代码示例中做了两件不同的事情。在第一个示例中,您将使用封闭类型的名称命名类型的成员。在第二种情况下,您将命名一个变量,其类型名称用作泛型类型参数。没有矛盾,它们完全不同。

实际上, 能够将变量命名为与其封闭类型相同的变量。您不能将成员命名为与其封闭类型相同。

public class Students
{
     public Students()
     {
        Students Students = new Students(); //bad idea, but it compiles
    }
}

如果您确实需要此行为,可以执行以下操作:

    public class StudentsBase
    {
         public List<Students> Students;
    }

    public class Students : StudentsBase
    {
        public Students() 
        {
            Students = new List<Students>();
            Students.Add(new Students());
            Students.Add(new Students());              
        }
    }

至于“为什么”,我无法回答这个问题。