当前位置: 首页 > 知识库问答 >
问题:

如何在不装箱的情况下检查泛型参数是否为null

公孙志尚
2023-03-14
void Foo<T>(T obj)
    where T : IBar
    => obj.Baz();
void Foo<T>(T obj)
    where T : IBar
    => obj?.Baz();
void Foo<T>(T obj)
    where T : IBar
{
    if (!EqualityComparer<T>.Default.Equals(obj, default(T)))
        obj.Baz();
}
void Foo<T>(T obj)
    where T : struct, IBar
    => obj.Baz();

void Foo(IBar obj)
    => obj?.Baz();
void FooVal<T>(T obj)
    where T : struct, IBar
    => obj.Baz();

void FooRef(IBar obj)
    => obj?.Baz();

这个问题用泛型约束标记为重复,where T:struct和where T:class和旧标题,它是。所以我更新了标题,以便更好地表达我的问题。我想问的是,如何调用泛型方法并仅在参数不为null的情况下才使用该参数,而不使用装箱。

一些为链接问题解释的变通方法可以用来回答这个问题,但我仍然相信这是一个根本不同的问题。

共有1个答案

许丁雷
2023-03-14

刚刚遇到类似的问题,我想出了下面的解决方案:

void Foo<T>(T obj)
{
  if (obj is object)
    obj.Baz();
}

如果obj为null或值为null的可空类型,则is操作的结果总是false,如果不是,则检查是否存在从tobject的装箱转换,这种转换总是存在的。

除非编译器根本没有进行优化,否则这实际上最终应该只是null检查,或者是非空类型的noop。

 类似资料:
  • 问题内容: 我想知道an 是否为空,但是没有使用方法。有没有办法知道它是否为空,而无需从中读取? 问题答案: 我想你在找。它不会告诉您它是否为空,但可以指示您是否要读取数据。

  • 问题内容: 这是@Jimt在Go中编写的工作程序和控制器模式的一个很好的示例, ” 但是此代码也有一个问题:如果要在退出时删除工作通道,则会发生死锁。 如果您使用,下次控制器写入该命令将导致恐慌,因为go无法写入一个已关闭的通道。如果您使用某些互斥锁来保护它,则由于它不会从通道读取任何内容,并且将阻止写入,因此互斥锁将导致死锁。您还可以为频道提供更大的缓冲,以解决此问题,但这还不够。 因此,我认为

  • 我正在使用docker-compose在linux服务器(centos)中管理我的容器“abc”。 我想完成的步骤: 1)docker撰写拉abc以拉取我的最新图像 2)docker命令检查我的容器'abc'是否需要更新(可能???) 3) 如果我的容器是“abc”,我将执行docker编写up-d 备注:我知道第3步是检查并在必要时更新容器,但如果第2步返回True,我需要执行预任务

  • 将本身赋值给似乎并不让编译器担心,而且如果的参数是而不是时,也不会出现问题。 不幸的是,似乎没有一种方法来命名参数类型,这样我就可以再次将其用作的类型和/或用一个老式的内部类替换lambda。 例如,这在语法上甚至是不允许的: 编译器接受这一点,但出于让类型检查器高兴的原因而进行的间接调用并不是我所说的真正优雅的调用。

  • 问题内容: 我知道Go将来不会有泛型,并且有一些建议可以用其他结构代替它们。但是在下面的例子中,我陷入了困境。 您可能会猜到,我试图使任何错误均告失败,并且希望将任何返回两个结果的函数放到第二个错误中。这工作正常,但丢失了它的类型信息,并且结果中只是一个空接口。 由于我也正在调用lib函数,因此我看不到使用Interfaces或Reflection解决此问题的方法。 有任何想法吗?我是完全走错了道

  • 问题内容: 有没有一种方法可以确定给定的示例实体类: 所谓“新”,是指有人调用了新的A()甚至可能设置了名称,但从未保存或保留。 通常,人们可以检查id,但是我想要一种不需要id或getId()方法的解决方案。 基本上,即使在分离模式下,此实体也已持久化到数据库中。 @Version或getVersion也不是令人满意的解决方案。 也许是独立的|| isAttached可能有效,但是我不确定如何在