C#: 调用非泛型方法的方式从泛型方法中

15
class CustomClass<T> where T: bool
{
    public CustomClass(T defaultValue)
    {
        init(defaultValue); // why can't the compiler just use void init(bool) here?
    }
    public void init(bool defaultValue)
    {

    }
    // public void init(int defaultValue) will be implemented later
}

你好。这似乎是一个简单的问题,但我在互联网上找不到答案:为什么编译器不使用 init 方法?我只是想为不同类型提供不同的方法。

相反,它会输出以下错误信息: “'CustomClass.init(bool)' 的最佳重载方法有一些无效的参数”

如果能给一些提示,我将非常感激。

祝好, Chris


3
为什么不使用 public void init(T defaultValue) - jcolebrand
6
编译器应该更早地发出警告:你不能使用 where T: bool - dtb
2
这句话的意思是什么??Boolean是一个密封类,不能继承。所以你的T只能是一个布尔类型。 - Aliostad
2
@Chris,不确定你想要实现什么。编译器告诉你T != bool,并且没有适当的从T到bool的转换。我怀疑你没有跨多个类型具有相同行为,因此通用类不是最佳解决方案。你考虑过使用接口(或基类)和不同类型的实现(或子类)吗?为什么你要在这里使用一个通用类?你试图解决什么问题? - Hamish Smith
1
@Chris ~ 在类构造函数中,不要只是调用 init(bool),而是应该加上判断条件 if (T is bool) init(bool) - jcolebrand
显示剩余6条评论
1个回答

38
编译器无法使用init(bool),因为在编译时它无法知道Tbool。你所要求的是动态分派——实际调用哪个方法取决于参数的运行时类型,在编译时无法确定。
您可以通过使用dynamic类型来在C# 4.0中实现此目的:
class CustomClass<T>
{
    public CustomClass(T defaultValue)
    {
        init((dynamic)defaultValue);
    }
    private void init(bool defaultValue) { Console.WriteLine("bool"); }
    private void init(int defaultValue) { Console.WriteLine("int"); }
    private void init(object defaultValue) {
        Console.WriteLine("fallback for all other types that don’t have "+
                          "a more specific init()");
    }
}

2
+1,这似乎是OP想要表达的。此外,dynamic的使用很有趣。我偶尔也想使用switch语句来处理类型,这似乎是一种模拟效果的有趣方式。 - Kirk Woll
非常感谢您的快速回复。在我看来,由于程序中已经存在带有bool参数的构造函数调用,因此可以在编译时决定。动态关键字是一个很好的特性。我该如何在C# 3.5中解决这个问题? - Chris
1
@Chris:仅仅因为你使用bool调用构造函数并不意味着编译器可以发出对init(bool)的调用。稍后你可能会从另一个程序集中使用不同类型的参数调用相同的构造函数!—不幸的是,我的解决方案只适用于C# 4.0及以上版本。没有C# 3.5。如果您需要使用C# 3.0(或者也许您指的是.NET 3.5?),那么您唯一的选择就是使用一系列的if ((object)defaultValue is bool) ... else ... - Timwi
我是说.NET 3.5。非常感谢您的支持。 - Chris
1
谢谢。作为一名C++程序员,当我刚刚遇到这个问题(在编写我的应用程序时)时,它让我感到惊讶。您的答案简单而优雅。谢谢! - Simon Parker

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接