Can Boolean operators ever produce a non-Boolean result? - c#

Please note, this question is not about the correctness of this style/convention, only about the use of Boolean operators. Just wanted to mention the style to give context.
Microsoft's C# Coding Conventions states that implicit typing is allowed "for local variables when the type of the variable is obvious from the right side of the assignment."
In the following code:
bool x = X();
bool y = Y();
var z = x && y;
Does the Boolean operator in the declaration of z make its type "obvious"? In other words, is there any situation in C# where && can be used with an x and y that are not Boolean, and produce a result that is not Boolean?

Are && and || guaranteed to return a boolean? No. Will they almost always result in a boolean? Most definitely.
By way of a counter example for && returning a non-boolean, consider the following:
public class Foo
{
public int Val { get; }
public Foo(int val) { Val = val; }
public static bool operator true(Foo val) {
return val.Val > 0;
}
public static bool operator false(Foo val) {
return val.Val <= 0;
}
public static Foo operator &(Foo left, Foo right) {
return new Foo(left.Val & right.Val);
}
public static Foo operator |(Foo left, Foo right) {
return new Foo(left.Val | right.Val);
}
}
Now we have a class that has indirectly overloaded the && and || operators, and they return type Foo.
The specification has this to say about user defined && and || operators:
When the operands of && or || are of types that declare an applicable user-defined operator & or operator |, both of the following must be true, where T is the type in which the selected operator is declared:
• The return type and the type of each parameter of the selected operator must be T. In other words, the operator must compute the logical AND or the logical OR of two operands of type T, and must return a result of type T.
• T must contain declarations of operator true and operator false.
Now, we evaluate the following:
var foo = new Foo(5) && new Foo(4);
foo is of Type Foo, with a Val of 4, as 5 & 4 is 4.
All of that said, I would not expect to see this kind of behavior outside of very specific circumstances.
Additionally, as the specification points out, the result of && or || must be the type of the parameters. In a bool && bool or bool || bool scenario, this should always be bool. So long as you're doing your logical operations on booleans (and not strange random non-boolean types) you should expect the result to be a bool.

Yes, it is possible for that to return something that is not a boolean as long as it can be evaluated as a boolean.
This requires you to overload the true and false operators, take this strange type:
public class MyStrangeType
{
public static readonly MyStrangeType Strange1 = new MyStrangeType(0);
public static readonly MyStrangeType Strange2 = new MyStrangeType(1);
private int myValue;
public int Value { get { return myValue; } }
private MyStrangeType(int value)
{
myValue = value;
}
public static bool operator true(MyStrangeType x) { return x.myValue == 1; }
public static bool operator false(MyStrangeType x) { return x.myValue != 1; }
public static MyStrangeType operator &(MyStrangeType x, MyStrangeType y)
{
return new MyStrangeType(3);
}
}
Now when you do something like this:
var result = MyStrangeType.Strange1 && MyStrangeType.Strange2;
result is not a boolean but a MyStrangeType.
Try it out!
public class Program
{
public static void Main()
{
var result = MyStrangeType.Strange1 && MyStrangeType.Strange2;
Console.WriteLine(result.GetType().FullName);
}
}
Outputs:
MyStrangeType

I could maybe misunderstood your question but this maybe could help to you or someone else.
There is "is" operator. You can check a veriable is a type of something.
For example;
var z = x is bool && y is bool;

You have two separate questions.
is there any situation in C# where && can be used with an x and y
that are not Boolean, and produce a result that is not Boolean?
This is shown by the other answers.
Does the Boolean operator in the declaration of z make its type "obvious"?
Yes, if x and y are bools. Since the && operator applied on boolean operands always returns a bool, which is defined in the specification. C# doesn't really allow variable return types for the same overload, except for the case of using the dynamic keyword. But then var is just inferred as dynamic as well.

Related

C# : Convert an object to Boolean depending on a class variable

My class looks something like this:
public class Testclass
{
public int myValue;
}
In another context I want to simply check the value of myValue against 0.
So I would write:
Testclass tc = new Testclass();
tc.myValue = 13;
if (tc.myValue == 0)
{
}
How would it be possible to simplify this so that the Testclass object knows when it is compared to a boolean? (or used as a boolean value) to write:
Testclass tc = new Testclass();
tc.myValue = 13;
if (tc)
{
}
To be more precise, the Testclass will be the result of another method that is included in a library, so the code would look like this:
anotherClass ac =new anotherClass();
// if (ac.AMethod().myValue == 0)
// should be
if (ac.AMethod())
{
}
Where AMethod would look like this:
public Testclass AMethod()
{
return new Testclass();
}
[Edit at 2016-04-13]:
Like Dennis wrote, i am using
public static implicit operator bool(TestClass value)
to get the "Boolean Value" of my class. To be a bit more precise and to stick more to my real application i would like to change the signature to
public static implicit operator UInt64(FlexComDotNetFehler fehler)
public static implicit operator Boolean(FlexComDotNetFehler fehler)
So these two methods of class FlexComDotNetFehler return the internal UInt64 field in the first case as the real representation as UInt64and in the second one as a Boolean value, that is true, when the UInt64 value is > 0.
But now, when i code
FlexComDotNetFehler x;
FlexComDotNetFehler y;
if (x == y)
where x and y are both of type FlexComDotNetFehler
the compiler cant know if it should use the Boolean or the UInt64 operator.
So i wrote
if ((UInt64)x != (UInt64)y)
but then those two type casts are greyed out.
#Ɖiamond ǤeezeƦ: thanks for your reformatting and editing. But I think now i got i right?
Greetings Wolfgang
BTW is there a playground where i can test the formatting and its output? And how do i send private messages to other users?
Define implicit cast operator for TestClass:
class TestClass
{
public int myValue;
public static implicit operator bool(TestClass value)
{
// assuming, that 1 is true;
// somehow this method should deal with value == null case
return value != null && value.myValue == 1;
}
}
Also think about converting TestClass from class to structure (see this reference). If you'll decide to convert it, avoid mutable structures.
you can use extension methods to implement method you can use any time not only for this class Testclass
public static class IntExtension
{
public static bool IsBool(this int number)
{
bool result = true;
if (number == 0)
{
result = false;
}
return result;
}
}
and then yo can
if ((ac.AMethod()).IsBool())
{}

C# Operator Overloading, rewriting string?

I'm very fresh to C#
Currently learning Operator overloading
i'm trying to do something like this:
string val = 500; (I can't implicitly)
and then
Number n1 = val;
I manages to get the Number n1 = someintvalue, for instance:
Number n1 = 500;
like this:
public struct Number
{
public int Value { get; set; }
public Number(int Val)
{
Value = Val;
}
public static implicit operator Number(int num)
{
return new Number(num);
}
}
However, when trying to make Number n1 = val; (when val is a string)
I simply cant since the first line cant compile:
string val = 500;
and the following wont work:
public static implicit operator string(int A)
{
return new string(A);
}
because of 1 error which i can not understand
1)User-defined conversion must convert to or from the enclosing type
by the way i get the idea of op overload
underthis specific case of: return new Number(num);
I simply init the ctor
still need some more fundemental understanding
thx ahead!
I presume the function you quote is within the Number class. You have added a conversion operator from an int to a string within that class, which is not legal. You can only add operators that convert to or from the type they're defined in, such as:
public static implicit operator string(Number A)
{
return new string(A.Value);
}
which will fail because string does not have a constructor that takes an int. You could do:
public static implicit operator string(Number A)
{
return A.ToString();
}
But the standard way to "convert" to a string is to overload the ToString method, which the compiler often calls automatically when a conversion to string is requested:
public override string ToString()
{
return Value.ToString();
}

Overloading Primitive Operator (C#)

Is there a way I can overload primitives, for example addition with doubles? I want to automatically round the doubles whenever an operation is performed. My current code is this:
class Test{
public static double operator +(double x, double y){
return Math.Round(x + y)
}
}
but there's an unfortunate error that says "One of the parameters of a binary operator must be the containing type".
No, and this would be horrible. Users using your library would suddenly get different behaviors from their double variables!
You can write and use a wrapper object however:
public struct MyDouble
{
public double Value {get; set;}
public MyDouble(double initValue)
{
Value = initValue;
}
public static double operator +(MyDouble x, MyDouble y){
return Math.Round(x.Value + y.Value)
}
}
You can also make it castable to/from a double, among other options. This way users know they are using your object and won't be surprised when their math operations are rounded.
If you want to assign from a simple double, you would need to define an implicit operator, similar to that of Nullable<T> (source):
public static implicit operator MyDouble(double value) {
return new MyDouble(value);
}
You can't overload operators on primitive types. This would cause havoc in your codebase.
What you can do instead, is to create a simple wrapper around the primitive type, let's say RoundedDouble:
public struct RoundedDouble : IEquatable<RoundedDouble>, IComparable<RoundedDouble>
{
public readonly double Value;
public RoundedDouble(double value)
{
Value = Math.Round(value); // Or anything else
}
public static implicit operator RoundedDouble(double value)
{
return new RoundedDouble(value);
}
public static implicit operator double(RoundedDouble wrapper)
{
return wrapper.Value;
}
public int GetHashCode()
{
return Value.GetHashCode();
}
public bool Equals(object other)
{
if (other is RoundedDouble)
return ((RoundedDouble)other).Value == Value;
return false;
}
public string ToString()
{
return Value.ToString();
}
// Add your operators here, and implement the interfaces
}
This is a structure. It has the same value semantics as a double.
Extend it by adding the operators, and by implementing at least IEquatable<RoundedDouble> and IComparable<RoundedDouble>.

C# dynamic casting during operator evaluation

I currently have a user defined type
class MyType {
double x;
double y;
double z;
//This class has operator overloading implemented
public static MyType operator + (double a,MyType b){
...
}
}
At some point later I will have an array (object[]) some of them double and some MyType. I would like to do evaluation over them but compiler is not allowing operator '+' to be applied to type object and object. What should I do here?
When resolving a + in code the compiler needs to bind it to a specific operation. The type object has no + operation and the compiler has no idea that the underlying types are double and MyType and hence the compiler errors out.
In order to fix this you will need to either
statically convert the elements to double and MyType so the compiler can properly bind the + operator
use dynamic and rely on the runtime binding to the correct operator+.
Here is an example of the latter method.
class MyType {
double _value;
internal MyType(double value) {
_value = value;
}
public static MyType operator +(double left, MyType right) {
return new MyType(left + right._value);
}
public static MyType operator +(MyType left, double right) {
return new MyType(left._value + right);
}
public static MyType operator +(MyType left, MyType right) {
return new MyType(left._value + right._value);
}
public static implicit operator MyType(double other) {
return new MyType(other);
}
}
class Program
{
static void Main(string[] args) {
object[] them = new object[] {
42,
new MyType(13),
12,
new MyType(12)
};
dynamic all = them;
MyType sum = 0;
foreach (dynamic element in all) {
sum += element;
}
Console.WriteLine(sum);
}
}
Honestly, I would create a MyType constructor that took a single double parameter, and use that to convert each double to a MyType, so that you could just use a MyType[] (or List<MyType>).
I understand that's really not what you're asking, but you'd still be able to handle the MyType creation such that the addition will perform properly, and you'd be more type-safe with your array.
You should be more specific with your types - the reason you cannot add is because object could be anyting in the system.
Is there any way that you can change object for a more specific type?
If it absolutely has to be object then you will have to evaluate at run-time using casts or the as operator or some similar mechanism.
eg
public static MyType operator +(object o, MyType b)
{
MyOtherType mot = o as MyOtherType;
if(o!=null)
...
but be in no doubt that your solution here raises questions about your design choices

Operators and inheritance

My brain has turned to jelly, or I'm having an out of mind experience, or something. I'm tinkering with a class hierarchy that looks a bit like this:
My Money class looks like this:
public abstract class Money
{
public int Amount { get; set; }
public static bool operator ==(Money leftSide, Money rightSide)
{
// Money can only be equal if it is in the same currency.
if (leftSide.GetType() != rightSide.GetType()) return false;
return leftSide.Amount == rightSide.Amount;
}
public static bool operator !=(Money leftSide, Money rightSide)
{
// If the currencies are different, the amounts are always considered unequal.
if (leftSide.GetType() != rightSide.GetType()) return true;
return leftSide.Amount != rightSide.Amount;
}
public static Money operator *(Money multiplicand, int multiplier)
{
var result = multiplicand * multiplier;
return result;
}
public static Dollar Dollar(int amount)
{
return new Dollar(amount);
}
public static Franc Franc(int amount)
{
return new Franc(amount);
}
}
My Dollar operator * looks like this:
public static Dollar operator *(Dollar multiplicand, int multiplier)
{
var result = multiplicand.Amount * multiplier;
return new Dollar(result);
}
Now, if I run this test code, I get a Stack overflow (wahoo!)
{
Money fiveDollars = Money.Dollar(5);
Money timesTwo = fiveDollars*2;
}
I had expected that this would recursively call the subclass (Dollar) operator *, which would return a definite result since (Dollar * int) is defined non-recursively. Since this doesn't work, the alternative is that I have done something dumb. Why doesn't this work? What would be the right way to get this behaviour?
You seem to have left out .Amount
public static Money operator *(Money multiplicand, int multiplier)
{
var result = multiplicand.Amount * multiplier;
return result;
}
The problem is that you expect that you can override operators in derived classes and expect dynamic binding. This is not the way it works in C#. Operators are overloaded and the actual overload is chosen compile-time. This means that the following code is recursive and calls itself:
public static Money operator *(Money multiplicand, int multiplier)
{
var result = multiplicand * multiplier;
return result;
}
Another example where you can see the difference between operator overloading and method overriding is this:
int a = 5;
int b = 5;
Console.WriteLine(a == b); // true
Console.WriteLine(a.Equals(b)); // true
Console.WriteLine((object)a == (object)b); // false
Console.WriteLine(((object)a).Equals((object)b)); // true
In the third case, C# treats a and b as objects instead of integers, so it uses the default == operator that is used for objects: comparing references (in this case the references of boxed integers).
This can make it awkward to define operators on a class hierarchy where you want to redefine the operators in derived classes. It is especially awkward when the behavior depends on the combination of both operands, since C# (and most other OOP languages) lacks support for multiple dispatch. You can solve this by using the visitor pattern, but I think in this case you should reconsider if using subclasses for each currency is the best solution.

Categories

Resources