There are this, this and this questions about Enum VS Property name conflicts.
My question is not about the naming conventions, instead I'd like to know how to solve the name conflict demonstrated in the code below:
namespace Test
{
public class Person
{
// 1)
// Gender? Gender { get; set; }
// 2)
Gender Gender { get; set; }
public Person ()
{
// 1 - Error CS1061: Type `Test.Gender?' does not contain a definition for `Male' and no extension method `Male' of type `Test.Gender?' could be found (are you missing a using directive or an assembly reference?) (CS1061) (Test)
// 2 - OK
Gender = Gender.Male;
}
}
public enum Gender
{
Male = 1,
Female
}
}
If I declare the property as in 2) Gender Gender { get; set; }
the code compiles successfully, however, if I declare as in 1) Gender? Gender { get; set; }
(commented in the code above) i get the error
Error CS1061: Type `Test.Gender?' does not contain a definition for `Male' and no extension method `Male' of type `Test.Gender?' could be found (are you missing a using directive or an assembly reference?) (CS1061) (Test)
Why does it happen ?
Gender?
means Nullable<Gender>
, this means that when you write Gender.Male
the compiler thinks you are trying to invoke a getter on a property called Male
on the Nullable<Gender>
instance, i.e. Gender
is interpretted as a read of the this.Gender
property and Male
as the read of a property called Male
upon the result of that.
The compiler does not identify case (2) as an error as enums cannot have methods so the only resolution that makes sense is for the symbol is the enum itself.
You can fix this by increasing the name qualification:
namespace Acme.Fruits.Banana
{
...
public Person()
{
Gender = Banana.Gender.Male
}
...
}
A property or local variable has precedence over a type/enum, this means that if one declares a variable or property with the same name as a type/enum the compiler will resolve any usage of the identifier as the variable/property.
public class Test
{
public static void SomeMethod(){}
}
public static void Main()
{
Test.SomeMethod();//ERROR... cannot use variable before declaring it.
object Test = new object();
Test.SomeMethod();//ERROR... object does not have a method SomeMethod
}
The only exception to this rule is if the property/variable has the same name as its own type, in which case the compiler allows it to access static members.
public class Test
{
public static void SomeMethod(){}
}
public static void Main()
{
Test Test = new Test();
Test.SomeMethod();//Works
}
However a nullable type is not the same as the type it encloses, instead the name is in the form of Nullable<T>
, and there is only an implicit cast between the two, therefore in the case of a nullable the compiler will no longer allow access to the enum members or static properties.
public struct Test
{
public static void SomeMethod(){}
}
public static void Main()
{
Test? Test = new Test();
Test.SomeMethod();//ERROR... Test does not have method SomeMethod
}
In a similar fashion it has to be the typed declarion of the variable as the compiler needs to be about it, the following will not work for example:
public class Test
{
public static void SomeMethod(){}
}
public static void Main()
{
object Test = new Test();
Test.SomeMethod();////ERROR... object does not have a instance method SomeMethod
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With