2012-12-29 21 views
5

当运行的代码此位的WriteLine显示,Equation(10, 20)是输出到控制台:支持转换为Boolean但仍然已经使用的ToString

public class Equation 
{ 
    public int a; 
    public int b; 

    public override string ToString() 
    { return "Equation(" + a + ", " + b + ")"; } 
} 

class Program 
{ 
    static void Main(string[] args) 
    { 
     Console.WriteLine(new Equation() { a = 10, b = 20 }); 

     Console.ReadLine(); 
    } 
} 

我想支持Equation实例中的测试使用一个if所以我允许隐式转换Boolean

public class Equation 
{ 
    public int a; 
    public int b; 

    public override string ToString() 
    { return "Equation(" + a + ", " + b + ")"; } 

    public static implicit operator Boolean(Equation eq) 
    { return eq.a == eq.b; } 
} 

class Program 
{ 
    static void Main(string[] args) 
    { 
     if (new Equation() { a = 10, b = 10 }) 
      Console.WriteLine("equal"); 

     Console.WriteLine(new Equation() { a = 10, b = 20 }); 

     Console.ReadLine(); 
    } 
} 

但是,麻烦的是,现在,当我上Equation使用WriteLine,它得到的转换ŧ o Boolean而不是使用ToString打印。

我该如何允许隐式转换为Boolean,仍然有WriteLine显示使用ToString


更新

这个问题是由EquationSymbolicC++启发。下面的代码说明了一个Equation可以经由cout被显示以及在if的测试中使用:

auto eq = x == y; 

cout << eq << endl; 

if (eq) 
    cout << "equal" << endl; 
else 
    cout << "not equal" << endl; 

所以这是可能以某种方式在C++中。

回答

7

你不能用一个bool转换做到这一点,但你可以重载truefalse运营商为Equation。当然Equation不会隐式转换为bool任何更多,但你仍然可以使用它在ifwhiledofor语句和条件表达式(即?:运营商)。

public class Equation 
{ 
    public int a; 
    public int b; 

    public override string ToString() 
    { return "Equation(" + a + ", " + b + ")"; } 

    public static bool operator true(Equation eq) 
    { 
     return eq.a == eq.b; 
    } 

    public static bool operator false(Equation eq) 
    { 
     return eq.a != eq.b; 
    }  
} 

从你的例子:

if (new Equation() { a = 10, b = 10 }) 
    Console.WriteLine("equal"); // prints "equal" 

Console.WriteLine(new Equation() { a = 10, b = 20 }); // prints Equation(10, 20) 
+0

哇,你钉牢了Mike。谢谢! – dharmatech

+0

虽然“方程式”在您列出的语句中工作,但似乎它们不适用于运算符'||'和'&&'。只是想我会提到这个人谁正在考虑这个选项。 – dharmatech

+0

@dharmatech正如我所说,它不再可以转换为'布尔'。你也可以重载'&'和'|'运算符,但是它的使用是有限的,因为你仍然不能像'eq && true'这样做。我真的同意Jon的评论,认为这样的事情有点太聪明,可能会让代码和未来维护者的消费者感到困惑。 –

12

据我所知,你不能。你可以提供一个转换为字符串...但这会使呼叫在WriteLine(string)WriteLine( bool之间不明确)。

我个人倒强烈建议您沟隐式转换Boolean。隐式转换几乎是总是不好主意。他们使代码更加混乱,并导致无意识的过载更改,正如您找到的。

(我也想改变你的风格支撑,但是这是一个不同的问题。)

+2

实际上,你可以) – SergeyS

+0

乔恩,请通过 '麦克Z' 的答案。这非常符合我的要求。你认为这种方法有什么缺点吗? – dharmatech

+11

@dharmatech:好吧,它不会回答你所说的问题,这是为了保持隐式转换为'bool'。就个人而言,我不会让“真”和“虚”操作符超负荷 - 我会更加明确地说明事情。我发现,像这样的运营商试图“可爱”通常会导致代码难以维护。 YMMV当然 - 但我会非常小心。 –

8

这是因为Console.WriteLine(布尔)超载被调用,而不是Console.WriteLine(对象)。你可以明确地转换为对象,并要求超载将被称为:

Console.WriteLine((object)(new Equation() { a = 10, b = 20 })); 

或可替代expliciltly调用的ToString():

Console.WriteLine((new Equation() { a = 10, b = 20 }).ToString()); 
相关问题