代码之家  ›  专栏  ›  技术社区  ›  Sarah Vessels

为什么我不能用我想要的C多态性进行压缩?

  •  5
  • Sarah Vessels  · 技术社区  · 15 年前

    我想做的是:

    XmlWriter writer = XmlWriter.Create(
        (string.IsNullOrEmpty(outfile) ? Console.Out : outfile)
    );
    

    但是,这不会编译,因为在“system.io.textwriter”和“string”之间没有隐式转换,所以给出错误“无法确定条件表达式的类型”。上述代码简化了以下内容:

    XmlWriter writer;
    
    if (string.IsNullOrEmpty(outfile))
    {
        writer = XmlWriter.Create(Console.Out); // Constructor takes TextWriter
    }
    else
    {
        writer = XmlWriter.Create(outfile); // Constructor takes string
    }
    

    这两个电话 Create 是完全有效的,这可以编译。有没有一种方法可以使这个更紧凑,就像我试图用内联测试做的那样?

    对我来说,我想要的不起作用是没有意义的。从精神上考虑,似乎编译器会评估 string.IsNullOrEmpty(outfile) 要确定采取哪种情况:

    • 如果条件是真的,它会与 Console.Out 然后看到它需要多态地选择 XmlWriter.Create 这需要一个文本编写器。
    • 如果条件是错误的,它将与 outfile 然后看到它需要多态地选择 xmlWriter.create 那需要一根绳子。

    在ML中编程是否扭曲了我的大脑?

    7 回复  |  直到 15 年前
        1
  •  18
  •   Lee    15 年前

    您不能这样做的原因是编译器必须选择在编译时使用哪个create重载-您的方法将要求在运行时完成它。你能做的最短的可能是:

    XmlWriter writer = String.IsNullOrEmpty(outfile)
        ? XmlWriter.Create(Console.Out)
        : XmlWriter.Create(outfile);
    
        2
  •  7
  •   Chris    15 年前

    似乎每个人都在建议:

    XmlWriter writer = String.IsNullOrEmpty(outfile)
        ? XmlWriter.Create(Console.Out)
        : XmlWriter.Create(outfile);
    

    然而,这也是可行的:

    XmlWriter writer = XmlWriter.Create(string.IsNullOrEmpty(outfile)
        ? Console.Out : new StreamWriter(outfile));
    

    后者更接近于你最初的尝试,在我看来,更紧凑。

        3
  •  3
  •   Adam Sills    15 年前

    C编译器在编译期间选择静态执行的方法。编译时生成的IL是对特定方法的引用。多态性部分在运行时选择要执行的特定函数的实现时出现。

    你的?:语句是在运行时计算的,因此编译器无法确定要执行的方法。

    换成这个就行了。

    XmlWriter writer = string.IsNullOrEmpty(outfile) ? 
        XmlWriter.Create(Console.Out) :
        XmlWriter.Create(outfile);
    
        4
  •  2
  •   Joseph    15 年前

    问题是,您无法在编译时确定

    (string.IsNullOrEmpty(outfile) ? Console.Out : outfile)
    

    应该回来。它是字符串还是文本编写器?这只能在运行时确定,因此编译错误是因为?必须在编译时解析运算符。

    最好的办法是:

    XmlWriter writer = string.IsNullOrEmpty(outfile)
        ? XmlWriter.Create(Console.Out)
        : XmlWriter.Create(outfile);
    
        5
  •  2
  •   Mike Hofer    15 年前

    这里发生了一些事情。

    首先,“异常”发生的原因是三元运算符(tm),而不是您使用它的位置。问题在于,您有一个表达式试图返回两个不同的类型,但无法解析为单个公共基类型(对象除外)。

    此外,构造函数重载可能采用两种完全不同的类型,它们之间没有任何关系。C编译器非常, 非常 很聪明,但不是很聪明 那个 聪明。

        6
  •  1
  •   Guffa    15 年前

    不,您必须进行两个单独的调用,因为它们是两个单独的构造函数。

    要调用的重载是在编译时确定的,因此不能在运行时选择要调用不同重载的数据类型。

    另外,条件运算符只能返回一个数据类型,不能让它根据选择返回不同的数据类型。

        7
  •  1
  •   mfeingold    15 年前

    C是静态类型化的,所有的多态魔术都发生在编译时。并且条件表达式的类型在编译时是未知的。