我有一个像这样定义的泛型方法:
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),这是我开始的地方.有没有更好的方法来解决这个问题?
我需要支持两种引用类型和值类型.
我正在针对我们的核心框架编写单元测试,并且遇到了这个问题.
我们有一个扩展方法,如下所示:
public static T ThrowIfDefault<T>(this T self, string variableName)
{
if (self.Equals(default(T)))
throw new ArgumentException(string.Format("'{0}' cannot be default(T)", variableName));
return self;
} // eo ThrowIfDefault<T>
Run Code Online (Sandbox Code Playgroud)
(ThrowIfNull<>我在Stack Overflow上看到的扩展方法的变体.
在为此编写测试用例时,我首先编写了一个帮助器:
public void ThrowIfDefaultTestHelper<T>(T value)
{
// unit test *itself* requires that a value be specified!!
Assert.AreNotEqual(default(T), value);
// Good test
GenericExtensionMethods.ThrowIfDefault(value, "value");
// Bad test
try
{
GenericExtensionMethods.ThrowIfDefault(default(T), "value");
}
catch (ArgumentException)
{
// Expected result
}
catch (Exception)
{
throw;
}
}
Run Code Online (Sandbox Code Playgroud)
然后是以下内容:
[TestMethod()]
public void ThrowIfDefaultTest()
{ …Run Code Online (Sandbox Code Playgroud) 我目前有一个通用的方法,我想在它们之前对参数进行一些验证.具体来说,如果type参数的实例T是引用类型,我想检查它是否是null,ArgumentNullException如果它为null则抛出它.
有点像:
// This can be a method on a generic class, it does not matter.
public void DoSomething<T>(T instance)
{
if (instance == null) throw new ArgumentNullException("instance");
Run Code Online (Sandbox Code Playgroud)
请注意,我不希望使用来约束我喜欢的类型参数class的约束.
我以为我可以用马克Gravell的答案在"我怎么比一般类型为默认值?" ,并像这样使用EqualityComparer<T>类:
static void DoSomething<T>(T instance)
{
if (EqualityComparer<T>.Default.Equals(instance, null))
throw new ArgumentNullException("instance");
Run Code Online (Sandbox Code Playgroud)
但它在调用时给出了一个非常模糊的错误Equals:
无法使用实例引用访问成员'object.Equals(object,object)'; 用类型名称来限定它
如何在不限制为值或引用类型的情况下检查T反对的实例?nullT