2

小さなコードを書きましたが、驚くべきものを見つけました。私はクラス名Studentsを持っており、その中でcalssは変数名Students(クラス名と同じ)でこのように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

クラスの名前はStudentsであるため、同じ名前を付けることができるメンバーはコンストラクターだけです。

于 2012-08-21T07:45:06.650 に答える
1

クラス内で同じ名前で宣言すると、コンパイラはそのクラスか変数かを判断しますが、他のクラスで宣言すると、ドット表記は次のようになります。

Program.Students

そして今、コンパイラは2つの違いを見ることができます。

于 2012-08-21T07:47:17.357 に答える
1

クラスメンバーに関するC#言語仕様のドキュメントは、特にあなたのケースに関連しています。


class-declarationは新しい宣言スペースを作成し(セクション3.3)、class-declarationにすぐに含まれるclass-member-declarationsは、この宣言スペースに新しいメンバーを導入します。次のルールがclass-member-declarationsに適用されます。

•インスタンスコンストラクタ、デストラクタ、および静的コンストラクタは、すぐに囲むクラスと同じ名前である必要があります。他のすべてのメンバーは、すぐに囲むクラスの名前とは異なる名前を持っている必要があります。

•定数、フィールド、プロパティ、イベント、またはタイプの名前は、同じクラスで宣言されている他のすべてのメンバーの名前とは異なる必要があります。

•メソッドの名前は、同じクラスで宣言されている他のすべての非メソッドの名前とは異なる必要があります。さらに、メソッドのシグニチャ(セクション3.6)は、同じクラスで宣言されている他のすべてのメソッドのシグニチャとは異なる必要があります。

•インスタンスコンストラクターのシグネチャは、同じクラスで宣言されている他のすべてのインスタンスコンストラクターのシグネチャとは異なる必要があります。

•インデクサーの署名は、同じクラスで宣言されている他のすべてのインデクサーの署名とは異なる必要があります。

•演算子のシグネチャは、同じクラスで宣言されている他のすべての演算子のシグネチャとは異なる必要があります。


コンストラクターは常にクラスと同じ名前であり、コンストラクターを明示的に指定しなくても、デフォルトのコンストラクターが存在します。コンストラクターは常に存在し、基本的にそのクラスメンバー名に対する権利を主張しているため、他のクラスメンバーに同様の名前を付けることはできません(もちろん、デストラクタと静的コンストラクターの特殊な場合を除く)。

PS:VBにはコンストラクターの異なるルールと名前があります。そのため、上記は適用されません。

于 2012-08-21T07:47:27.180 に答える
1

同じクラスではなく、他のクラスのクラス名としてカスタム変数を作成するにはどうすればよいですか?

これはそうではありません。コード例では、2 つの異なることを行っています。最初の例では、囲んでいる型の名前で型のメンバーに名前を付けています。2 番目のケースでは、ジェネリック型パラメーターとして使用される型名で変数に名前を付けています。矛盾はありません、それらは完全に異なるものです。

実際には、変数にそれを囲む型と同じ名前を付けることができます。メンバーを囲む型と同じ名前にすることはできません。

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 に答える
1

同じクラスでは、クラスまたはメンバーに対処しているかどうかがあいまいになりますが、別のクラスではそうではありません。

また、 List of Students の方がList of Studentより直感的に聞こえるかもしれませんが、クラスStudentが 1 人の学生を表す場合はクラスに名前を付ける必要があります。単一の参照を保持している場合、それは間違っているように見えます。

于 2012-08-21T07:44:14.863 に答える