这是编译器错误吗? [英] Is this a compiler bug?

查看:92
本文介绍了这是编译器错误吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述




我有一些奇怪的编译器行为,所以我希望这里的一位大师

能够告诉我是否真的是一个编译器错误。


简而言之,编译器说它不能在两个

重载版本的方法之间做出选择,恕我直言,一个超载显然是一个b $ b更好的选择比另一个。我已经查看了

重载决策的所有规则,我看不出编译器的

错误消息的任何理由。


我将包括一个关于bug的精简演示。下面。但首先,

"免责声明:是的,我已经在一个

的类中包含了一个隐含转换运算符,是的,如果我删除了问题就会消失它。但是,不管我是否已经包含它,我仍然相信编译器是错误的./ />

您怎么看?


这里是代码:


公共类A

{

公共静态隐式运算符B(A a)

{

返回新B(); //实际执行省略

}

}


公共类B

{

}


公共类ShowError

{

public static void方法(A a,B b)

{}


public static void方法(B b,A a)

{}


public static void ThisFailsToCompile()

{

A a = new A();

方法(a,null);

//编译器说这个调用不明确,但是b $ b //肯定方法(A a,B b)优于方法(B b,A a)

//因为前者不需要隐式转换第一个

参数

}


}


John

解决方案

John,


如果你给Method(a,null)无所谓;或者方法(null,a)无论是哪种方式如果它是方法((B)a,null)或方法(a,null)
$ b $,编译器都不清楚
应该叫做b。隐式转换指南隐式转换

应该非常明确,不应造成混淆。在这种情况下,

令人困惑。


谢谢,

Po


John Rusk <乔****** @ discussions.microsoft.com>在留言中写道

news:51 ********************************** @ microsof t.com ...



我有一些奇怪的编译器行为,所以我希望这里的一位大师
能够告诉我它是否真的是一个编译器错误。

简而言之,编译器说它不能在两个
重载版本的方法之间进行选择时,恕我直言,一个重载是显然是更好的选择比另一个。我查看了重载决策的所有规则,我看不出编译器的错误信息的任何理由。

我''将包括bug的简化演示。下面。但首先,
免责声明:是的,我在一个类中包含了一个隐含的转换运算符,是的,如果我删除了问题就会消失它。但是,无论我是否已将其包括在内,我仍然认为编译器对于模糊性是错误的。

你怎么看?

这里是代码:

公共类A
公共静态隐式运算符B(A a)
{
return new B(); //实际实现省略
}

公共课B
公共类ShowError {
public static void方法(A a,B b)
{}

public static void方法(B b,A a)
{}

public static void ThisFailsToCompile()
一个a = new A();
方法(a,null);
//编译器说这个调用是不明确的,但是
//肯定方法(A a,B b)比方法(B b,A a)更好
//因为前者要求没有隐含的第一个转换
param
}


John



Po,
<如果是方法((B)a,null)或者应该调用Method(a,null)
,那么编译器不清楚blockquote class =post_quotes>。


恕我直言,C#文档说Method(a,null)是更好的匹配

因为它的第一个参数已经是正确的类型。这比

优于Method((B)a,null),其中第一个参数需要

转换。因此,根据文档,编译器应该

自动选择Method(a,null)。

隐式修改指南隐式转换
应该非常明确不应该造成混乱。在这种情况下,它会让人感到困惑。




对于人类,是的!我的观点是,根据文档,

应该_not_混淆编译器。


John


PS:我确实有充分的理由写出这样的混乱。码;我只是没有时间和空间在这里描述它们。无论如何,重点是

_compiler_不应该混淆。


John Rusk< Jo ***** *@discussions.microsoft.com>写道:

我有一些奇怪的编译器行为,所以我希望这里的一位大师能够告诉我它是否真的是编译器错误。




不,这不是一个错误,虽然它很微妙。


第一个论点支持Method( A,B)。但是,关于更好的列表,请查看第二个

参数。转换,其中T1是

A,T2是B,C1是从null类型到A的转换,C2是从null类型到B的转换,以及S是空类型。


o T1和T2是不同的转换(没有结果)

o S既不是T1也不是T2(没有结果)

o *是*从T1到T2的隐式转换,并且没有从T2到T1的隐式

转换,因此C1是更好的转换。


因此,对于第二个参数,方法(B,A)是首选 - 所以编译器

不知道该怎么做。


希望有所帮助 - 如果您希望我通过更多

详细信息,请告诉我。 (看起来你已经花了很多时间仔细研究这些规格,

所以希望现在上面应该非常简单!)


-

Jon Skeet - < sk *** @ pobox.com>
http://www.pobox.com/~skeet 博客: http://www.msmvps.com/jon.skeet

如果回复小组,请不要给我发邮件


Hi,

I have some weird compiler behaviour, so I''m hoping that one of the gurus
here will be able to tell me whether or not it really is a compiler bug.

In short, the compiler is saying that it cannot choose between two
overloaded versions of a method when, IMHO, one overload is clearly a
"better" choice than the other. I''ve looked through all the rules for
overload resolution, and I can''t see any justification for the compiler''s
error message.

I''ll include a stripped down demonstration of the "bug" below. But first, a
"disclaimer": yes, I have included an implict conversion operator on one of
the classes and yes, the problem does go away if I remove it. However,
regardless of the fact that I''ve included it, I still believe the compiler is
wrong about the ambiguity.

What do you think?

Here''s the code:

public class A
{
public static implicit operator B(A a)
{
return new B(); //actual implementation omitted
}
}

public class B
{
}

public class ShowError
{
public static void Method(A a, B b)
{ }

public static void Method(B b, A a)
{ }

public static void ThisFailsToCompile()
{
A a = new A();
Method(a, null);
//Compiler says this call is ambiguous, BUT
//Surely Method(A a, B b) is better than Method(B b, A a)
//since the former requires NO implicit conversion of the first
param
}

}

John

解决方案

John,

Do not matter if you give Method(a, null); or Method(null, a) either way it
is not clear to the compiler if it is Method((B)a, null) or Method(a, null)
should be called. Guidelines for implicit maintions that implicit conversion
should be very clear and should not create confusion. In this case it is
confusing.

Thanks,
Po

"John Rusk" <Jo******@discussions.microsoft.com> wrote in message
news:51**********************************@microsof t.com...

Hi,

I have some weird compiler behaviour, so I''m hoping that one of the gurus
here will be able to tell me whether or not it really is a compiler bug.

In short, the compiler is saying that it cannot choose between two
overloaded versions of a method when, IMHO, one overload is clearly a
"better" choice than the other. I''ve looked through all the rules for
overload resolution, and I can''t see any justification for the compiler''s
error message.

I''ll include a stripped down demonstration of the "bug" below. But first,
a
"disclaimer": yes, I have included an implict conversion operator on one
of
the classes and yes, the problem does go away if I remove it. However,
regardless of the fact that I''ve included it, I still believe the compiler
is
wrong about the ambiguity.

What do you think?

Here''s the code:

public class A
{
public static implicit operator B(A a)
{
return new B(); //actual implementation omitted
}
}

public class B
{
}

public class ShowError
{
public static void Method(A a, B b)
{ }

public static void Method(B b, A a)
{ }

public static void ThisFailsToCompile()
{
A a = new A();
Method(a, null);
//Compiler says this call is ambiguous, BUT
//Surely Method(A a, B b) is better than Method(B b, A a)
//since the former requires NO implicit conversion of the first
param
}

}

John



Po,

is not clear to the compiler if it is Method((B)a, null) or Method(a, null)
should be called.
IMHO, the C# documentation says that Method(a, null) is the better match
because its first parameter if already of the correct type. That makes it
better than Method((B)a, null), in which the first parameter requires
conversion. Therefore, according to the documentation, the compiler should
automatically choose Method(a, null).
Guidelines for implicit maintions that implicit conversion
should be very clear and should not create confusion. In this case it is
confusing.



For humans, yes! My point is that, according to the documentation, it
should _not_ confuse the compiler.

John

PS: I do have good reasons for writing such "confusing" code; I just don''t
have time and space to describe them here. Anyway, the point is that the
_compiler_ should not get confused.


John Rusk <Jo******@discussions.microsoft.com> wrote:

I have some weird compiler behaviour, so I''m hoping that one of the gurus
here will be able to tell me whether or not it really is a compiler bug.



No, it''s not a bug, although it''s subtle.

The first argument favours Method(A, B). However, look at the second
argument, with respect to the list of "better" conversions, where T1 is
A, T2 is B, C1 is the conversion from the null type to A, C2 is the
conversion from the null type to B, and S is the null type.

o T1 and T2 are different conversions (no result)
o S is neither T1 nor T2 (no result)
o There *is* an implicit conversion from T1 to T2, and no implicit
conversion from T2 to T1, so C1 is the better conversion.

So, for the second argument, Method(B,A) is preferred - so the compiler
doesn''t know what to do.

Hope that helps - let me know if you want me to go through it in more
detail. (It looks like you''ve spent time poring over the specs already,
so hopefully the above should be pretty straightforward by now!)

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too


这篇关于这是编译器错误吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆