ToString的重载怎么可能不带零参数?零参数ToString是System.Object!
的一部分编辑以响应近距离投票: 由于我无法将构建服务器升级到.NET 4.5,是否有任何方法可以使此代码与.NET 4.0 / VS 2010编译器?没有为我的重载提供一个完全不同的名称,这并不酷。
我想最简单的解决方法是将我的ToString重载重命名为其他内容,但这很奇怪。
这是一个简单的复制品。您可以在此处下载包含此代码的解决方案的zip文件:http://dl.dropbox.com/u/1742470/CS1501_Repro.zip
在VS 2010中编译该解决方案将失败“CS1501:方法'ToString'没有重载需要0个参数”。在VS 2012中编译它将工作得很好。在这两种情况下,我们都将.NET Framework 4作为目标。
F#
namespace CS1501_Repro.FSharp
open System
[<Serializable>]
type MyDiscriminatedUnion =
| Foo of int list
| Bar of string
| Baz of int
| Fizz of float
| Buzz of DateTimeOffset
override this.ToString() =
"Zero Arguments"
member this.ToString(lookup:Func<int,string>) =
"One Argument"
C#
using System;
using CS1501_Repro.FSharp;
namespace CS1501_Repro.CSharp
{
public class Caller
{
private MyDiscriminatedUnion _item;
public Caller(MyDiscriminatedUnion item)
{
_item = item;
}
public string DoThing()
{
return _item.ToString();
}
public string DoOtherThing()
{
return _item.ToString(i => i.ToString());
}
}
}
答案 0 :(得分:6)
这只是部分答案,但我注意到VS2010和VS2012为F#类生成不同的IL。如果您查看IL的ToString(lookup:Func<int,string>)
方法,那么您将看到VS2010中的输出为:
.method public instance string ToString(class [mscorlib]System.Func`2<int32,string> lookup) cil managed
{
// Code size 7 (0x7)
.maxstack 3
IL_0000: nop
IL_0001: ldstr "One Argument"
IL_0006: ret
} // end of method MyDiscriminatedUnion::ToString
,VS2012中的输出为:
.method public hidebysig instance string
ToString(class [mscorlib]System.Func`2<int32,string> lookup) cil managed
{
// Code size 7 (0x7)
.maxstack 8
IL_0000: nop
IL_0001: ldstr "One Argument"
IL_0006: ret
} // end of method MyDiscriminatedUnion::ToString
区别在于方法签名中的hidebysig
注释。如果添加了hidebysig
,则该方法将隐藏共享相同名称和签名的其他实现(在基类中),而如果省略hidebysig
,则将隐藏具有相同名称的所有其他实现即使签名不同。 This stack overflow question包含一个描述hidebysig
的好答案。
所以虽然这个答案没有解决你的问题,但它解释了为什么它不能在VS2010中编译。
答案 1 :(得分:5)
我不得不承认,这是我第一次使用F#,所以这个解决方案可能不是最优雅的,但是,你提到ToString()是System.Object的一部分......
我通过在DoThing()方法中添加一行代码来解决这个问题,该方法将_item分配给object,然后从对象调用ToString(),在这个例子中给出了所需的结果:
F#代码(未更改)
type MyDiscriminatedUnion =
| Foo of int list
| Bar of string
| Baz of int
| Fizz of float
| Buzz of DateTimeOffset
override this.ToString() = "Zero Arguments"
member this.ToString(lookup:Func<int,string>) = "One Argument"
C#代码(请参阅DoThing()方法中的更改)
public class Caller
{
private Module1.MyDiscriminatedUnion _item;
public Caller(Module1.MyDiscriminatedUnion item)
{
_item = item;
}
public string DoThing()
{
object result = _item; //assign to object
return result.ToString(); //call ToString() on object
}
public string DoOtherThing()
{
return _item.ToString(i => i.ToString());
}
}
如果这不是你想要的,我会道歉...但这是我能想到的,如果有人认为这是错误的方式,请说出原因!