从 Nullable 隐式转换
Implicit conversion from Nullable
我想创建一个类似于 Nullable 的 class 除了它可以与 classes 和结构一起工作的那一刻:
public class MyWrapper<T>
{
public MyWrapper(T value)
{
Value = value;
}
public T Value { get; set; }
}
然后我想添加 Nullable 到 MyWrapper 的隐式转换:
public static implicit operator MyWrapper<T> (Nullable<T> value)
{
return new MyWrapper<T>(value);
}
当然,由于 Nullable 限制,它失败了:
Only non-nullable value type could be underlying of 'System.Nullable'
这是一个非常容易理解的错误,但理论上,我可以将任何 Nullable 转换为 MyWrapper,因为 Nullable 的限制比 MyWrapper 的限制更难。
那么 Nullable 到 MyWrapper 隐式 转换有什么解决方法吗?
为什么我需要为 classes 使用 MyWrapper?
我们在后端使用某种糟糕的 GraphQl 并像这样发送更新 objects:
class UpdateProductRequest
{
public MyWrapper<string> Country {get;set;}
public MyWrapper<string> Title {get;set;}
}
所以
new UpdateProductRequest
{
Title = "new title"
}
更新标题,但不更新国家。
您可以定义从基础类型到 MyWrapper
:
的隐式转换
public static implicit operator MyWrapper<T> (T value)
{
return new MyWrapper<T>(value);
}
现在有了这样的运算符你可以这样做:
MyWrapper<int> w = new int?(5);
MyWrapper<int> w2 = (int?)null; //here casting method is not called
所以最初 Nullable
被转换为基础类型,然后转换为 MyWrapper
。如果它为 null,则只是对 MyWrapper
类型变量的 null 赋值,即 class,因此它是有效的。 Nullable
编译器对其进行了特殊处理,因此它看起来像魔术,但确实有效。
我想创建一个类似于 Nullable 的 class 除了它可以与 classes 和结构一起工作的那一刻:
public class MyWrapper<T>
{
public MyWrapper(T value)
{
Value = value;
}
public T Value { get; set; }
}
然后我想添加 Nullable 到 MyWrapper 的隐式转换:
public static implicit operator MyWrapper<T> (Nullable<T> value)
{
return new MyWrapper<T>(value);
}
当然,由于 Nullable 限制,它失败了:
Only non-nullable value type could be underlying of 'System.Nullable'
这是一个非常容易理解的错误,但理论上,我可以将任何 Nullable 转换为 MyWrapper,因为 Nullable 的限制比 MyWrapper 的限制更难。
那么 Nullable 到 MyWrapper 隐式 转换有什么解决方法吗?
为什么我需要为 classes 使用 MyWrapper?
我们在后端使用某种糟糕的 GraphQl 并像这样发送更新 objects:
class UpdateProductRequest
{
public MyWrapper<string> Country {get;set;}
public MyWrapper<string> Title {get;set;}
}
所以
new UpdateProductRequest
{
Title = "new title"
}
更新标题,但不更新国家。
您可以定义从基础类型到 MyWrapper
:
public static implicit operator MyWrapper<T> (T value)
{
return new MyWrapper<T>(value);
}
现在有了这样的运算符你可以这样做:
MyWrapper<int> w = new int?(5);
MyWrapper<int> w2 = (int?)null; //here casting method is not called
所以最初 Nullable
被转换为基础类型,然后转换为 MyWrapper
。如果它为 null,则只是对 MyWrapper
类型变量的 null 赋值,即 class,因此它是有效的。 Nullable
编译器对其进行了特殊处理,因此它看起来像魔术,但确实有效。