Compiler confusion with nullable types

I

Israel

I have the following class which gets this error when I compile it
using C# 2.0:
'System.Nullable<System.DayOfWeek>' does not contain a definition for
'Monday'

class MyClass
{
public MyClass()
{
m_DayOfWeek = DayOfWeek.Monday;
}

public DayOfWeek? DayOfWeek
{
get { return m_DayOfWeek; }
set { m_DayOfWeek = value; }
}
private DayOfWeek? m_DayOfWeek;
}

If I don't use a nullable type it compiles fine. I can understand
that it's a difficult parsing problem to realize that this should be
legal but it's always done such a good job figuring out what
"DayOfWeek" meant in the past based on the context so why has the
compiler given up in this situation and forced me to scope the enum
with "System."? Is there a situation where the compiler could
actually make the wrong decision and allow this to compile the wrong
code? I can see situations where it would be ambiguous if the enum
had a value "HasValue" and then the compiler could just say it's
ambiguous but if it's not ambiguous the compiler could just pick the
only valid option.
 
H

Hans Kesting

Israel was thinking very hard :
I have the following class which gets this error when I compile it
using C# 2.0:
'System.Nullable<System.DayOfWeek>' does not contain a definition for
'Monday'

class MyClass
{
public MyClass()
{
m_DayOfWeek = DayOfWeek.Monday;

change this to
m_DayOfWeek = System.DayOfWeek.Monday;
}

public DayOfWeek? DayOfWeek
{
get { return m_DayOfWeek; }
set { m_DayOfWeek = value; }
}
private DayOfWeek? m_DayOfWeek;
}

The compiler got confused between the property DayOfWeek and the enum
System.DayOfWeek.

Hans Kesting
 
H

Hans Kesting

Hans Kesting was thinking very hard :
Israel was thinking very hard :

change this to
m_DayOfWeek = System.DayOfWeek.Monday;


The compiler got confused between the property DayOfWeek and the enum
System.DayOfWeek.

Hans Kesting

Sorry, now that I re-read your post I see that you already know this.

Hans Kesting
 
J

Jon Skeet [C# MVP]

Israel said:
I have the following class which gets this error when I compile it
using C# 2.0:
'System.Nullable<System.DayOfWeek>' does not contain a definition for
'Monday'

class MyClass
{
public MyClass()
{
m_DayOfWeek = DayOfWeek.Monday;
}

public DayOfWeek? DayOfWeek
{
get { return m_DayOfWeek; }
set { m_DayOfWeek = value; }
}
private DayOfWeek? m_DayOfWeek;
}

If I don't use a nullable type it compiles fine. I can understand
that it's a difficult parsing problem to realize that this should be
legal but it's always done such a good job figuring out what
"DayOfWeek" meant in the past based on the context so why has the
compiler given up in this situation and forced me to scope the enum
with "System."? Is there a situation where the compiler could
actually make the wrong decision and allow this to compile the wrong
code? I can see situations where it would be ambiguous if the enum
had a value "HasValue" and then the compiler could just say it's
ambiguous but if it's not ambiguous the compiler could just pick the
only valid option.

It's resolving DayOfWeek in the "DayOfWeek.Monday" to be
"this.DayOfWeek" - i.e. the property, not the type. If you rename your
property to anything else, it will be fine.
 
J

Jon Skeet [C# MVP]

Peter Duniho said:
I think that the main question the OP is wondering about is why the name
conflict only causes a problem when the type of the property is
Nullable<System.DayOfWeek>, and not when the type of the property is
System.DayOfWeek.

I have to admit, I have the same confusion as the OP. It's difficult to
understand why the compiler would resolve "DayOfWeek" to the property when
the property type is nullable, but not when it's non-nullable. At the
very least, it seems like the compiler would _always_ resolve the name
"DayOfWeek" to the type, or _always_ resolve it to the property. Why does
the _type_ of the property affect how the compiler resolves the name?

I assume that if I took the time to read the C# specification carefully,
I'd find the answer. But it's not something that is readily apparent off
the top of my head.

Hmm, yes, you're right.

I'm sure you're well aware that I can't resist a little challenge like
that :)

It's section 7.5.4.1 of the C# 3.0 spec:

<quote>
In a member access of the form E.I, if E is a single identifier, and if
the meaning of E as a simple-name (§7.5.2) is a constant, field,
property, local variable, or parameter with the same type as the
meaning of E as a type-name (§3.8), then both possible meanings of E
are permitted. The two possible meanings of E.I are never ambiguous,
since I must necessarily be a member of the type E in both cases. In
other words, the rule simply permits access to the static members and
nested types of E where a compile-time error would otherwise have
occurred.
</quote>

There's then an example which pretty much mimics the code in this
question (when not using Nullable<DateTime>).
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top