Should a property have the same name as its type?
Asked Answered
M

10

82

I've sometimes seen code written like this :

public class B1
{
}

public class B2
{
    private B1 b1;

    public B1 B1
    {
        get { return b1; }
        set { b1 = value; }
    }
}

i.e. class B2 has a property named "B1", which is also of type "B1".

My gut instinct tells me this is not a good idea, but are there any technical reasons why you should avoid giving a property the same name as its class ?

(I'm using .net 2.0, in case that matters).

Monarchy answered 8/7, 2009 at 1:11 Comment(3)
I believe that the .NET framework design guidelines recommends this naming convention as well.Kannry
which naming convention - calling them the same thing, or changing case for differentiation?Savate
@Savate The only naming convention mentioned here, namely using the same name for the type and property.Algonkian
A
75

It's fine. The canonical example here is

public Background {
    public Color Color { get; set; }
}

There are rare issues (corner cases) that come up here, but not enough to warrant avoiding this device. Frankly, I find this device quite useful. I would not enjoy not being able to do the following:

class Ticker { ... }


public StockQuote {
    public Ticker Ticker { get; set; }
}

I don't want to have to say Ticker StockTicker or Ticker ThisTicker etc.

Aryanize answered 8/7, 2009 at 1:16 Comment(6)
class A { public static void Method(int i) { } public void Method(object o) { } } and class B { A A { get; set; } public B() { A = new A(); A.Method(0); } }. Is A.Method calling the static method named Method or is it calling the instance method named Method? (In C# it turns out that it will call the static method. However, if you replace the 0 in A.Method(0) by "Hello, world!" it will call the instance method. Note that Intellisense doesn't pick this up and will highlight the A in A.Method("Hello, world!") blue as if it were the static method.)Aryanize
And this is merely to point out that there can be (rare) cases wherein the intent of the code using this pattern is not crystal clear (there is, of course, always an unambiguous interpretation based on the language specification).Aryanize
@Aryanize Properties I agree, but objects why? Don't you want to distinguish your static (class) method calls from your instance calls? If you have one object, I see no reason for A = new A(), just do a = new A(). It is no more onerus but much clearer. Your edge case concerns objects, not properties. However you closed the question concerning objects. In VB, intellisense and renaming do not distinguish between class and instance references when object and class are the same name. But renaming properties with same name as the type is no problem.Highroad
@Jason See this question for problems to do with renaming in VB projects, when objects are named the same as their class. This does not apply to properties, but my question about naming objects the same as their class, was closed as a duplicate of this one.Highroad
@Aryanize Your edge case also means that if you rename the object reference, A in A=new A() to a for instance, A.Method("Hello, world!") will not be renamed, causing a NullReferenceException at runtime. Another reason not to name objects the same as the class, but this is not an issue with properties! Renaming the property with the same name as its return type is not a problem.Highroad
BTW, this has since become somewhat more of an issue for me, with BindableProperty in WPF or Xamarin Forms. For example, I have a property Font. In defining BindableProperty FontProperty I need to refer both to property Font and to default value Font.Default, which is attempting to refer to class Font, but fails w/o further syntax to disambiguate. Still, its worth the tradeoff.Stamps
W
19

The Microsoft Naming Guideline for Members state:

Consider giving a property the same name as its type.

When you have a property that is strongly typed to an enumeration, the name of the property can be the same as the name of the enumeration. For example, if you have an enumeration named CacheLevel, a property that returns one of its values can also be named CacheLevel.

Though I admit there is a little ambiguity whether they are just recommending this for Enums or for properties in general.

Weatherley answered 4/4, 2012 at 9:30 Comment(3)
This is actually a horrible guideline since it doesn't work for nullable properties. It can be incredibly frustrating if you start with this guideline and later have to make the property nullable.Scrimshaw
@Scrimshaw Actually, coming from a Java background, for me using PascalCase instead of camelCase as a naming convention for type members is the true devil here. +1 for Java conventions. However, I just started learning C# so there are maybe contrasting cases.Eurystheus
@Eurystheus comparing languages or identifying devils in C# is not the topic here. C# is what it is ... the question here is about how to program in C# given its conventions.Algonkian
H
14

I can only think of one drawback. If you wanted to do something like this:

public class B1
{
        public static void MyFunc(){ ; }
}

public class B2
{
        private B1 b1;

        public B1 B1
        {
                get { return b1; }
                set { b1 = value; }
        }

        public void Foo(){
                B1.MyFunc();
        }
}

You'd have to instead use:

MyNamespace.B1.MyFunc();

A good example of this is common usage is in Winforms programming, where the System.Windows.Forms.Cursor class overlaps with the System.Windows.Forms.Form.Cursor property, so your form events have to access static members using the full namespace.

Hu answered 8/7, 2009 at 1:16 Comment(0)
K
11

Just today, Eric blogged about the 'Color Color' problem.

https://learn.microsoft.com/en-us/archive/blogs/ericlippert/color-color

Personally, I would avoid it if possible.

Kilbride answered 8/7, 2009 at 1:15 Comment(4)
Why? I don't see any harm to it.Thracian
@StevenSudit IMO it adds complexity for the programmer (after all, you need to read that article to understand what's going on), and we programmers know how bad & error-prone that is. I'd avoid it too.Keyser
What his article actually shows is that it is stupid to have both static and instance members with the same name. Which I would hope any programmer would avoid. Note this key sentence "In real situations the instance and static methods typically have different names". Note that the problems all arise because he declared static M and (instance) M. The discussion of Color Color just shows that combining Color Color with static M and M makes the problem worse. So don't do the original idiocy.Stamps
Did you read the article? He didn't say you should avoid it or give any reason why you should.Algonkian
J
9

Another gotcha is with inner types.

I run into this one all the time:

public class Car {
    public enum Make {
        Chevy,
        Ford
    };

    // No good, need to pull Make out of the class or create
    // a name that isn't exactly what you want
    public Make Make {
        get; set;
    }
}
Jesicajeske answered 8/7, 2009 at 1:46 Comment(2)
Which is why I pluralise my enum names. There are several possible Makes of car, but this car has only one Make. It doesn't always read the best, but I look at is as the enum being a list of possible Makes.Kata
I end up naming it CarMake. However C# naming convention is quite bad to generate such king of conflicts, We should have members and properties starting with a lowercase, to make them truly interchangeableHarquebus
R
4

There's no specific technical problem with it. It might harm or improve readability. In fact, some Microsoft libraries have these kind of properties (specifically, with enum properties, this usually makes sense).

Retrad answered 8/7, 2009 at 1:15 Comment(0)
R
4

This common pattern is one of the reasons why I always use this when referring to an instance member within a class. e.g. always

this.SomeMethod(this.SomeProperty);

and never

SomeMethod(SomeProperty);

In most cases, there isn't any actual ambiguity, but I find it helps clarify things. Plus you now know where the property/method is defined.

Rochette answered 8/12, 2009 at 18:52 Comment(0)
S
2

There is actually an important case where it is not fine to have a property with the same name as its type: nullables.

The following will surprisingly throw a compiler error:

public enum MyEnum
{
    Option1,
    Option2
}

public class A
{
    public MyEnum? MyEnum { get; set; } = MyEnum.Option1;
}

It can be especially frustrating if earlier in the design you make the property not nullable, and later the need comes to make it nullable: all your assignments which used to work fine everywhere will suddenly stop working.

Scrimshaw answered 24/3, 2023 at 22:4 Comment(7)
The property does not have the same name as the type in that case. I would call the property OptionalMyEnum, MyEnumMaybe, etc.Algonkian
I just started to learn C# three days ago, so pls. forgive my ignorance. But isn't this problem easily solvable by fully qualifying the expression on the right hand side by providing the namespace of the enum (in this case, where no explicit namespace is defined, global::MyEnum.Option1)? Ultimately, at the point of the expression the property is already declared and is used as the type because of the narrower scope, I guess. I am more surprised to see this work without the nullable modifier than to not see it work with it. @Jim It has the same name, right? You just wouldn't do it like that.Eurystheus
@Eurystheus the problem affects not just the declaration of the property default value, but every single assignment to the property anywhere inside the class code. The reason this is a problem is precisely that it does work without nullable, and is the recommended naming convention: learn.microsoft.com/en-us/dotnet/standard/design-guidelines/…Scrimshaw
@Eurystheus It is common and even recommended practice to "do it like that".Algonkian
@Jim Sorry, since the guideline is to use the same name, this has become a bit ambiguous: I am quite confident you mean using Optional* or *Maybe is recommended. In that case I am not sure I will adopt that practice. It is also good practice to not repeat the type of a member in its name. Like I wouldn't name a list of, let's say Horses, horseList but merely horses in Java. The ? more or less resembles Java's Optional<T> class here, so I would refrain from explicitly repeating the intent of ? . But maybe time will prove me wrong.Eurystheus
@Eurystheus No I don't mean that. And I'm not interested in what practices you will adopt, nor is it relevant ... this isn't a blog. Now please stop pinging me ... this is an old topic (2009) and I'm retired and no longer program in C# or have any interest in it.Algonkian
I'll gladly respect your retirement from now on. Note, though, that the answer you commented on is rather recent. Also note that being more precise on your comments may prevent pinging in the first place. And while this is not a blog, comments are there for discussion (which you started btw., at least with regard to naming practices).Eurystheus
G
1

It can obviously be a bit confusing when the name of a property and it's type are the same, but other than that it's not really a problem.

If the name makes sense, it's usually better to let the name and the type be the same. If you can think of a better name, you should of course use that, but you should not try to make up a name at any cost just to avoid this situation.

Goulder answered 8/7, 2009 at 1:31 Comment(0)
P
0

I give things the same name as their type, except for case: my methods and properties are "lowerCase"; and I therefore wouldn't have the problem that MiffTheFox has.

public class B1
{
    public static void myFunc(){ ; }
}

public class B2
{
    private B1 m_b1;

    public B1 b1
    {
        get { return m_b1; }
        set { m_b1 = value; }
    }

    public void Foo()
    {
        B1.myFunc(); //this is Ok, no need to use namespace
    }
}

So for me, m_b1 is member data, b1 is a property (or a local variable or parameter), and B1 is the name of the class.

Pelagianism answered 8/7, 2009 at 1:45 Comment(3)
Unfortunately using lower-case for Properties and Methods is in direct conflict with the accepted naming guidelines for C#.Isolecithal
Yes. They're inferior guidelines, IMO, don't you agree? Why did they come to be?Pelagianism
Its a trade-off as to which maximizes clarity / minimizes misunderstanding. Consider a typical code file of yours. Count all appearances of all class names, member names, and local variable names. You'll find that class names are a small fraction of the total appearances of named items. So your choice assigns "lowercase" to a strong majority of name appearances. Therefore, you assign a high value to distinguishing "class" from "not class". Nothing wrong with that, but the recommended style instead distinguishes "local" from "not local". Maybe off-balanced in opposite way...Stamps

© 2022 - 2024 — McMap. All rights reserved.