首页 > 解决方案 > 具有不同类型操作数的空合并运算符

问题描述

我知道您不能将不同的类型复合成一个结果,但我不明白为什么会这样。

例如。

Guid? ID;
int ID2;
var ID3 = ID ?? ID2;

无论、 var 、 object 等的可空性ID或类型如何,上述代码都不起作用。ID3

谁能解释为什么不允许这样做?

我的实际代码如下所示:

public StandAloneMachine Get(int id, Guid? FKGuid = null, string FKName = "") 
{ 
    var parameters = new Parameters() 
    { 
        new Parameter("id", FKGuid ?? id) 
    }; 
}

标签: c#null-coalescing-operator

解决方案


有没有人有理由不允许这样做?

这就是语言的设计方式。它应该怎么做?您如何将int32 位数字转换GUID为由多个数字部分组成的结构,反之亦然?

这段代码:

var ID3 = ID ?? ID2

翻译成类型意味着(伪代码):

(inferred type_) = Guid? ?? int;

并且??运算符自然要求其参数的类型兼容。实际规则相当复杂,可以在此处的 C# 语言规范中找到。

无论如何,null-coalescing 运算符返回单个值,并且它的左右参数都必须计算为相同类型的值。因此,结果可能aa 。那么将是这种类型。但是,不能将和操作数的值转换为这种单一类型的值。Guidint(inferred type)??Guidint

注意:您可能会争辩说编译器可以选择object与两者兼容的关闭类型Guidint并且只需将这些值装箱到一个对象中。但是,这会破坏强类型检查的意义。只是“太放松了”。

在您的特定示例中,坚持??似乎是人为的;在你的代码中,一个好的旧的?:和更多的表现力会做得更好,甚至可能有助于提高可读性:

var parameters = new Parameters() 
{ 
    new Parameter("id", FKGuid.HasValue ? ToTypeParameterExpects(FKGuid.Value) : ToTypeParameterExpects(id)) 
}; 

显然,是对' 的构造函数期望值的ToTypeParameterExpects任何类型的转换。Parameter


推荐阅读