我有一个像这样定义的泛型方法:
public void MyMethod<T>(T myArgument)
Run Code Online (Sandbox Code Playgroud)
我想要做的第一件事是检查myArgument的值是否是该类型的默认值,如下所示:
if (myArgument == default(T))
Run Code Online (Sandbox Code Playgroud)
但是这不能编译,因为我没有保证T将实现==运算符.所以我把代码改为:
if (myArgument.Equals(default(T)))
Run Code Online (Sandbox Code Playgroud)
现在这个编译,但是如果myArgument为null则会失败,这是我正在测试的一部分.我可以像这样添加一个显式的空检查:
if (myArgument == null || myArgument.Equals(default(T)))
Run Code Online (Sandbox Code Playgroud)
现在这让我感到多余.ReSharper甚至建议我将myArgument == null部分更改为myArgument == default(T),这是我开始的地方.有没有更好的方法来解决这个问题?
我需要支持两种引用类型和值类型.
我四处寻找,但找不到答案.说我有这个代码:
class Command<T> : ICommand<T>
{
public void Execute(T parameter)
{
var isNull = parameter == null;
// ...
}
}
Run Code Online (Sandbox Code Playgroud)
T可以是任何阶级,甚至是Nullable<>.如果T是值类型,执行上面的检查会导致装箱吗?我的理解是,这与调用ReferenceEquals两个object参数相同T,如果我理解正确的话,其中任何一个都会导致拳击,如果是值类型.
如果以上确实导致拳击,是否有更优选的方法来做到这一点而不会导致框发生?我知道有,default(T)但在int那种情况下0,我正在寻找这个值是否null没有拳击它.另外,我希望以满足值和引用类型的方式执行此操作.
例如,以下代码演示了我的思路:
class Program
{
static void Main(string[] args)
{
int i = 0;
IsNull(i); // Works fine
string s = null;
IsNull(s); // Blows up
}
static void IsNull<T>(T obj)
{
if (obj == null)
throw new NullReferenceException();
}
}
Run Code Online (Sandbox Code Playgroud)
还有以下代码:
int i = 0;
bool b = i == null; // Always false
Run Code Online (Sandbox Code Playgroud)
是否存在隐式对象?这样:
int i = 0;
bool b = (object)i == null;
Run Code Online (Sandbox Code Playgroud)