您是否曾经需要通知任何使用您的代码并传递一些引用类型参数的人不要传递 null?你肯定有。而且您应该为您的代码无法使用的每个“坏”变量抛出异常。
现在,让我们假设您已经创建了这个结构:
public struct NotNullable<T> where T : class
{
// Backing field for the value. Guaranteed to return not null.
private T _value;
public T Value
{
get
{
if (_value == null)
throw new ApplicationException("Value is not initialized.");
return _value;
}
}
// Easy both-ways convertible.
public static implicit operator T(NotNullable<T> notNullable)
{
return notNullable.Value;
}
public static implicit operator NotNullable<T>(T value)
{
return new NotNullable<T>(value);
}
// These members are overridden.
public override string ToString()
{
return Value.ToString();
}
public override int GetHashCode()
{
return Value.GetHashCode();
}
public override bool Equals(object obj)
{
if (obj is NotNullable<T>)
{
return Value.Equals(((NotNullable<T>)obj).Value);
}
return Value.Equals(obj);
}
public NotNullable(T value)
{
this._value = value;
}
}
这种结构的用法:
class Program
{
static void Main(string[] args)
{
NotNullable<string> a = "Hello World!";
Console.WriteLine(a);
Console.WriteLine((string)a);
Console.WriteLine((object)a);
Console.WriteLine((NotNullable<string>)a);
// Produces fine outputs.
var b = default(NotNullable<string>);
Console.WriteLine(b); // Throws an exception of non-initialized field.
}
}
您还可以使您的方法接收不可为空的引用类型参数:
List<Tree> treeList;
public void CreateTree(NotNullable<Tree> tree)
{
// Assume you cannot have the list contain nulls.
treeList.Add(tree); // No null-checks required.
}
在如此有用的与结构相反的情况下可能有什么问题Nullable<>
?