You get a warning because a value type will never be null. Full(er) explanation below.
A char
in C# is a value type, and can never be null. Consider the purpose of char
, that is to represent a Unicode character. There isn't really a good value to pick to mean null
in the 0x0 to 0xFFFFFFFF range. (It's true that UTF-16 doesn't actually encompass this entire range, but it might someday).
It's a bit easy to understand with something that has a much smaller range. Consider a byte
. It has a range of 0 - 255. Now, in order to represent null
, we would need to pick a manner in which null
could be stored. A few solutions end up coming up:
- Store information extra to the
byte
to represent null. Nullable<Byte>
does this.
- Pick a value in the valid
byte
range to instead actually mean null
. You end up needing to check for this value throughout an entire program. On a small scale, this is a non-issue, but when you don't know who's going to be using your code (a likely scenario), it's something you have to document and hope they see.
It's a much simpler implementation to provided non-nullable value types and a default and provide a wrapper around value types that can represent null
if needed. .NET does exactly this with the Nullable<T>
type and it's shortcuts with language support (int?
,byte?
, etc.).
To address your code, if classLetter
really could be any value a char
can represent, then you can use:
private char classLetter;
public char ClassLetter
{
get { return classLetter; }
set
{
classLetter = value;
RaisePropertyChanged("ClassLetter");
}
}
You can do this because the compiler will give the user a compile-time error if they try to do something to classLetter
they couldn't possibly do sanely.
If you have additional requirement about what classLetter
is supposed to represent, update your question and I'll update my answer.
In reponse to your comment on another answer: "I want the behavior to be simple. I want to be able to put any symbol, but I don't want the variable to be left empty"
The only other thing we need to settle on is what "empty" really means. What does empty mean in your context? Once you answer that, you can use default initialization in the type containing classLetter
to set it to that value. A generalized example:
class Foo {
private char classLetter;
public char ClassLetter {
get { return classLetter; }
set {
classLetter = value;
}
}
public Foo(char classLetter = 'A') {
this.ClassLetter = classLetter;
}
}
When a caller uses new Foo()
, they will get a Foo
instance where Foo.ClassLetter == 'A'
. Of course, A
can be any sensible default that meets your specific requirements.