2

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

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

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

...
}

这里编译时错误是

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

但是如果我在其他类中声明相同的列表......就像

        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++"));
          ............
        }

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

4

6 回答 6

7

错误消息中提到了答案:

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

如果您在与成员同名的类中,这只是一个错误。

无论如何,无论如何命名这样的变量都是一个坏主意。它们不应大写。

编辑:这是一个可能导致歧义的示例:

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:搜索了一下我发现了一个非常相似的问题:为什么 C# 成员名称不能与封闭类型名称相同?并且共识只是它是 C# 的一个限制(没有明确的解释为什么)。VB.NET 似乎允许这种情况发生。

于 2012-08-21T07:42:50.827 回答
3

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

于 2012-08-21T07:45:06.650 回答
1

无论您是针对班级还是成员,在同一个班级中都是模棱两可的,而在另一个班级中则不是。

此外,如果该类Student代表单个学生,则应为其命名,即使List of Students听起来可能比List of Student更直观。如果你持有一个单一的参考,它看起来是错误的。

于 2012-08-21T07:44:14.863 回答
1

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

Program.Students

现在编译器可以看到两者之间的区别。

于 2012-08-21T07:47:17.357 回答
1

关于类成员的 C# 语言规范文档与您的案例特别相关,它说:


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

• 实例构造函数、析构函数和静态构造函数必须与直接封闭类同名。所有其他成员的名称必须与直接封闭类的名称不同。

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

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

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

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

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


构造函数总是与类同名,即使你没有明确指定构造函数,默认构造函数也会存在。始终存在的构造函数基本上已经声明了对该类成员名称的权利,因此不允许任何其他类成员以同样的方式命名(当然除了析构函数和静态构造函数的特殊情况)。

PS:VB对构造函数有不同的规则和命名,这就是为什么上面不适用于那里。

于 2012-08-21T07:47:27.180 回答
1

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

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

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

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());              
        }
    }

至于“为什么”,我无法回答。

于 2012-08-21T08:21:50.230 回答