C# 如果结构不是',则检查C中结构的null;t可为空

C# 如果结构不是',则检查C中结构的null;t可为空,c#,.net,c#-4.0,C#,.net,C# 4.0,我有一些通用的方法 T SomeMethod(Func<T> func){ T result = func(); if (result != null) { //.....} } T方法(Func Func){ T结果=func(); 如果(结果!=null) { //.....} } 如果T为class,则效果良好。但是如果T是struct,我该怎么办?如果T是struct,如何检查result==default(T) 另外,我不想使用约束wher

我有一些通用的方法

T SomeMethod(Func<T> func){
   T result = func();
     if (result != null)
       { //.....}
}
T方法(Func Func){
T结果=func();
如果(结果!=null)
{ //.....}
}
如果
T
为class,则效果良好。但是如果
T
是struct,我该怎么办?如果
T
struct
,如何检查
result==default(T)


另外,我不想使用约束
where t:class
Nullable
类型

如果将
T
编译为
struct
,则与
null
的比较将始终计算为
false
。这在C语言规范第7.9.6节中有介绍

如果将类型参数类型T的操作数与null进行比较,并且运行时类型T是值类型,则比较结果为false


一种更惯用的方法是遵循
int.TryParse
之类的方法

public delegate bool TryFunction<T>(out T result);

T SomeMethod(TryFunction<T> func)
{
    T value;

    if(func(out value))
    {

    }
}
public委托bool TryFunction(out T result);
T SomeMethod(TryFunction func)
{
T值;
if(func(输出值))
{
}
}
考虑使用默认值(T):

private T SomeMethod(Func Func)
{
var result=func();
if(result.Equals(默认值(T)))
{
//处理。。。
返回默认值(T);
}
返回结果;
}

检查值类型是否等于默认值有什么用,以及这在逻辑上如何与
null
对象匹配?如果刚刚构造了一个引用类型,那该怎么办?这是等价的吗?我认为这不能笼统地回答,但必须根据您的场景逐一回答。要添加到@dlev
default(t)中,其中t:class==null
要扩展我之前的评论,如果您只是试图避免NRE,那么JaredPar的回答告诉您可以简单地编写
if(result!=null)
。这并不遵循
int.TryParse
的指导,而是建立在它的基础上。我不认为这是惯用的,但这不是一个坏主意。无论它是一般性地解决了原始问题还是只是旁敲侧击,这都是一个不同的问题(一个我无法回答的问题-检查我在OP上的评论,因为我认为这个问题不能一般性地回答)。
Func
不会编译。您必须为此创建新的委托类型。@svick:Good catch;我现在不在VS面前。尽管如此,这应该能奏效。@MerlynMorgan-Graham:我很好奇它为什么不“跟随它的领导”。通常的想法是将返回值移动到
out
参数中,并返回一个
bool
表示成功。我之所以称之为惯用语,是因为这种技术在框架中的几个地方都使用过,而且似乎符合要求。@Adam:投反对票的不是我。我只是有点迂腐,想弄清楚哪些部分是惯用的。委托的签名是惯用的(try方法),但采用try方法(泛型与否)并将其用作谓词并不惯用。这可能是个好主意。有趣的是,当您将可空结构与
null
进行比较时,它仍然返回
null
。您使用了哪一版本的规范?我读到:“如果B是一个类型参数,并且在运行时类型参数是一个可为null的类型或引用类型,那么结果就好像B类型的操作数被装箱,然后与null进行比较。”[ECMA 4th ed]@CodeInChaos我正在读C#3.5语言规范以供参考here@CodeInChaos:这是特定于
Nullable
(它本身就是一个结构体),赋值
null
的能力也是如此。这是语言(可能还有运行时;我对此不确定)中的一种功能,不能在用户类型上复制。@JaredPar,你的意思是
if(result!=null | | result==false)
?它对结构有效吗?如果
T
是引用类型,这将抛出
NullReferenceException
private T SomeMethod<T>(Func<T> func)
{
  var result = func();
  if (result.Equals(default(T)))
  {
    // handling ...
    return default(T);
  }
  return result;
}