Debhere
Debhere

Reputation: 1075

List<> is having different behaviour in different class

I have written a small code, but found something amazing. I have a class name Students and inside that calss declared a List<> like this with variable name Students (same as the Class name)

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

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

...
}

Here compile time error is

'Students': member names can not be the same as their enclosing type

But if I declare the same List in other class ... like

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

This Works fine. My Question is, why? How we can create custom variable as the class name in other calsses but not in the same class? Any elaborate answer would be good, as I want to gain knowledge in this.

Upvotes: 2

Views: 225

Answers (6)

mtijn
mtijn

Reputation: 3678

the C# language specification documentation on class members is particularly relevant for your case, it says this:


A class-declaration creates a new declaration space (Section 3.3), and the class-member-declarations immediately contained by the class-declaration introduce new members into this declaration space. The following rules apply to class-member-declarations:

•Instance constructors, destructors and static constructors must have the same name as the immediately enclosing class. All other members must have names that differ from the name of the immediately enclosing class.

•The name of a constant, field, property, event, or type must differ from the names of all other members declared in the same class.

•The name of a method must differ from the names of all other non-methods declared in the same class. In addition, the signature (Section 3.6) of a method must differ from the signatures of all other methods declared in the same class.

•The signature of an instance constructor must differ from the signatures of all other instance constructors declared in the same class.

•The signature of an indexer must differ from the signatures of all other indexers declared in the same class.

•The signature of an operator must differ from the signatures of all other operators declared in the same class.


constructors always have the same name as the class, and even if you don't specify a constructor explicitly a default constructor will exist. the constructor, being present always, has basically claimed the rights to that class-member name thus disallowing any other class-member to be named likewise (except of course for the special case of the destructor and static constructor).

PS: VB has different rules and naming for constructors, which is why the above does not apply there.

Upvotes: 1

Jason
Jason

Reputation: 1383

How we can create custom variable as the class name in other calsses but not in the same class?

This is not the case. You are doing two different things in your code examples. In your first example, you are naming a member of a type with the name of the enclosing type. In the second case, you are naming a variable with the type name used as a generic type parameter. There is no inconsistency, they are completely different things.

Actually, you are able to name variables the same as their enclosing type. You just can not name members the same as their enclosing type.

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

If you really need this behavior, you can do this:

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

As for the "why", I am not able to answer that.

Upvotes: 1

Tudor
Tudor

Reputation: 62439

The answer is mentioned in the error message:

'Students': member names can not be the same as their enclosing type

It's only an error if you are inside the class with the same name as the member.

Anyway, it's a bad idea in any case to name variables like this. They should be not be capitalized.

Edit: Here's an example that might cause ambiguity:

class A
{
    public void Foo() { }
}

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

    static void Foo() { }

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

Edit 2: Searching around a bit I've found a very similar question: Why C# member names can't be the same as the enclosing type name? and the consensus was just that it's a limitation of C# (no clear explanation why). VB.NET seems to allow that this situation to occur.

Upvotes: 7

Ravi Patel
Ravi Patel

Reputation: 2191

When you declare it with same name inside class how the compiler will determine if its a class or a variable but when you declare it in other class dot notation comes in like below.

Program.Students

and now compiler can see difference between two.

Upvotes: 1

Konstantin Chernov
Konstantin Chernov

Reputation: 1936

Your class is named Students, so obviously the only member allowed to be named same is constructor.

Upvotes: 3

Matthias Meid
Matthias Meid

Reputation: 12523

It would be ambiguous in the same class whether you're addressing the class or the member, whereas in another class it isn't.

Besides, you should name the class Student if it represents a single student, even though a List of Students may sound more intuitive than a List of Student. If you're holding a single reference, it looks wrong.

Upvotes: 1

Related Questions