关于c#:如果使用内联隐式转换中的奇怪行为

Strange behaviour in implicit conversion if inline if used

本问题已经有最佳答案,请猛点这里访问。

我有一种奇怪的行为,我想理解它。但我在网上找不到好的答案:(

这里是情况,我抽象了名称和逻辑来关注这个问题。有3种类型,A、B和C。B&C定义了隐式运算符以转换为对象。

1
2
3
4
5
6
7
8
public class A
{
    public static implicit operator A(B input){ /* Convert B to A */ }
    public static implicit operator A(C input) { /* Convert C to A*/ }
}

public class B { }
public class C { }

然后,当我执行此操作时,代码编译并正常工作:

1
2
3
4
5
A myObject = null;
if (condition)
    myObject = new B();
else
    myObject = new C();

但当我用内联if编写相同的逻辑时,我得到了一个错误:

1
A myObject = condition ? new B() : new C();

错误:

1
Type of conditional expression cannot be determined because there is no implicit conversion between 'B' and 'C'

你知道这种行为吗?

提前谢谢你。

致以最诚挚的问候,让它无故障运行!


Do you have any idea about this behaviour ?

绝对的。在有条件的A型算子的表达式必须是either型operand第二或第三型operand。。。。。。。(如果这些两个类型是T的同一,exactly一部类型的人是implicitly投资到其他的编译器。)没有尽到t find a"下的普通denominator"式的,和使用的结果是重要的either(编译器不"通知"…你重新分配的结果到一个变量的类型A)。 </P >

你能修理你自己,这是由explicitly铸造either operand: </P >

1
A myObject = condition ? (A) new B() : new C();

或 </P >

1
A myObject = condition ? new B() : (A) new C();

值得注意的是,这并不是T公司的用户定义的转换运营商;同样是真的简单的方法是基于参考conversions衍生类: </P >

1
2
3
Button x = new Button();
String y ="foo";
object z = condition ? x : y; // Compile-time error

七段7.14《C #规范的更多细节。 </P >


该错误是清澈的 </P >

there is no implicit conversion between 'B' and 'C'

你已经定义的隐式转换之间的ABAC。。。。。。。但是,有好的隐式转换之间的BC。。。。。。。 </P >

有条件的经营者requires: </P >

Either the type of first_expression and second_expression must be the
same, or an implicit conversion must exist from one type to the other.


乔恩:"跳汰机 后一种查表生成的MSIL代码页下面,我发现和它的真的很有趣。下面的两个方法,"我已经写的测试: </P >

1
2
3
4
5
6
7
8
9
10
11
12
13
static void ClassicalIf(bool condition)
{
    int i = 0;
    if (condition)
        i = 1;
    else
        i = 2;
}

static void InlineIf(bool condition)
{
    int i = condition ? 1 : 2;
}

这里的MSIL与评论,所以任何人可以明白怎么做和为什么S A德科工也隐式转换所需的方法是内联的语法。 </P >

方法:如果inline </P >

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
.method private hidebysig static void InlineIf(bool condition) cil managed
{
    .maxstack 1
    .locals init (
        [0] int32 i)
    L_0000: nop
    L_0001: ldarg.0         -- Load argument '0' onto the stack
    L_0002: brtrue.s L_0007 -- Branch to L_0007 if value is non-zero
    L_0004: ldc.i4.2        -- Push 2 onto the stack
    L_0005: br.s L_0008     -- Branch to L_0008
    L_0007: ldc.i4.1        -- Push 1 onto the stack
    L_0008: nop
    L_0009: stloc.0         -- Pop from stack into local variable 0
    L_000a: ret
}

和这里的一个中心的"正常的",如: </P >

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
.method private hidebysig static void ClassicalIf(bool condition) cil managed
{
    .maxstack 2
    .locals init (
        [0] int32 i,
        [1] bool CS$4$0000) -- Additional bool for if
    L_0000: nop
    L_0001: ldc.i4.0        -- Push 0 onto the stack
    L_0002: stloc.0         -- Pop from stack into local variable '0'
    L_0003: ldarg.0         -- Load argument '0' onto the stack
    L_0004: ldc.i4.0        -- Push 0 onto the stack
    L_0005: ceq             -- Push 1 if value1 equals value2 (on stack), else push 0.
    L_0007: stloc.1         -- Pop from stack into local variable '1'
    L_0008: ldloc.1         -- Load local variable '1' onto stack.
    L_0009: brtrue.s L_000f -- Branch to L_000f if value is non-zero
    L_000b: ldc.i4.1        -- Push 1 onto the stack
    L_000c: stloc.0         -- Pop from stack into local variable '0'
    L_000d: br.s L_0011     -- Branch to L_0011
    L_000f: ldc.i4.2        -- Push 2 onto the stack
    L_0010: stloc.0         -- Pop from stack into local variable '0'
    L_0011: ret
}

所以我也将尝试使用if的直列为可能的。用于指示(即CPU)和内存使用量较少。 </P >


你可能有一个查找表的remarks在???????运营商:(C #参考) 它的成员 </P >

Either the type of first_expression and second_expression must be the same, or an implicit conversion must exist from one type to the other.