Originally Posted by
nvoigt
I'm not sure that anything about nullable is "built in". Your code looks fine, try to test it and see if the assignment works. My guess would be that the implicit cast will be used. No magic.
we could have
Code:
struct S<T>
{
public static implicit operator S<T>(T t) { if (t != null) return new S<T>((T)t); return new S<T>(); }
}
S<object> s = 6;
Console.WriteLine(s);
Console.WriteLine(s = 3);
Console.WriteLine(s = null); //code won't compile
Console.WriteLine(s = 5);
but the above will require that the type parameter T not be a value type. otherwise, the above implicit operator will not allow the code to compile since a value type cannot represent null.
This also wouldn't compile because it is not possible to define a cast operator that converts from the object type to a derived type:
Code:
public static implicit operator S<T>(Object t) { if (t != null) return new S<T>((T)t); return new S<T>(); }
Does it mean that the problem is handled is by providing a "placeholder" class?
Code:
class PlaceHolder{}
struct S<T> where T : struct
{
private T the_value;
public S(T t)
{
this = new S<T>();
this.HasValue = true;
this.Value = t;
}
public T Value
{
private set { the_value = value; }
get {if (HasValue) return the_value; throw new InvalidOperationException(); }
}
public bool HasValue { private set; get; }
public static implicit operator S<T>(PlaceHolder t) { if(t == null) return new S<T>(); throw new InvalidCastException();}
public static implicit operator S<T>(T t) { return new S<T>(t);}
public static explicit operator T(S<T> t) { return t.Value; }
public override string ToString()
{
if (HasValue) return this.Value.ToString();
return "";
}
}
class P
{
static void Main(string[] args)
{
S<int> s = null;
Console.WriteLine(s = 7);
Console.WriteLine(s = 3);
Console.WriteLine(s = null);
Console.WriteLine(s = 5);
Console.Read();
}
}
If that's the way it's done, it's very interesting. Who would have thought that by assigning null to a nullable struct all we were doing was implicitly converting from an unknown reference type to a default instance of the nullable type?
Assuming that I'm on the right track, I still have one question,
The default value of my struct is not null. The default value of a Nullable struct is null. Is this more built-in special functionality? Or is it just that .NET code, unlike application code, can actually define default unary operators?
Code:
int? i = default(Nullable<int>); //i = null
S<int> j = default(S<int>); // j = default instance of S<int>