If (instance) / implicit boolean conversion on a custom class - c#

I have the following class:
public class InterlockedBool
{
private int _value;
public bool Value
{
get { return _value > 0; }
set { System.Threading.Interlocked.Exchange(ref _value, value ? 1 : 0); }
}
public static bool operator ==(InterlockedBool obj1, bool obj2)
{
return obj1.Value.Equals(obj2);
}
public static bool operator !=(InterlockedBool obj1, bool obj2)
{
return !obj1.Value.Equals(obj2);
}
public override bool Equals(bool obj)
{
return this.Value.Equals(obj);
}
}
My question is: Can I check if Value is true, without == true? The operator override works, but can I also use it like so?
InterlockedBool ib = new InterlockedBool();
if (ib) { }
Instead of (this works, but normally I omit the == true in if statements.
if (ib == true) { }
And how do I assign it to a value without use .Value =?
Thanks for you help :)

You need to be able to convert your object to and from a boolean
Implicit Conversion
Your object to a boolean:
public static implicit operator bool(InterlockedBool obj)
{
return obj.Value;
}
Then a boolean to your object:
public static implicit operator InterlockedBool(bool obj)
{
return new InterlockedBool(obj);
}
Then you can test it:
InterlockedBool test1 = true;
if (test1)
{
//Do stuff
}
Explicit Conversion
If you want the users of this class to be aware that there is a conversion happening, you can force an explicit cast :
public static explicit operator bool(InterlockedBool obj)
{
return obj.Value;
}
public static explicit operator InterlockedBool(bool obj)
{
return new InterlockedBool(obj);
}
Then you must explicitly cast your objects:
InterlockedBool test1 = (InterlockedBool)true;
if ((bool)test1)
{
//Do stuff
}
EDIT (due to OP comment)
In the conversion from boolean to your object, I call a constructor that you did not mention, here is how I would build it:
public InterlockedBool(bool Value)
{
this.Value = Value;
}
Therefore the setting of the value is guranteed thread-safe

You can define an implicit conversion to bool :
public static implicit operator bool(InterlockedBool obj)
{
return obj.Value;
}

Related

Can I return a different type from a function in a generic class depending on if the generic type used for the class is a value or a reference type?

I want to return a Nullable<Value> from a function in a generic class if Value is a value type, and just 'Value' if value is already a reference type.
I've been trying to work with where clauses to achieve this, but I can't seem to use a where class on a non-generic function, even in a generic class.
public class HashTable<Key, Value>
{
private List<ValueSlot> valueSlots = new List<ValueSlot>();
private struct ValueSlot
{
public bool hasValue;
public List<KeyValuePair<Key, Value>> values;
}
//...
public Nullable<Value> TryGetValue(Key key) where Value : struct
{
(bool result, Value value) = TryGetValue(valueSlots, key);
if (result == true)
{
Nullable<Value> myVal = value;
return myVal;
}
else
{
return null;
}
}
public Value TryGetValue(Key key) where Value : class
{
(bool result, Value value) = TryGetValue(valueSlots, key);
return result == true ? value : (Value)null;
}
private (bool, Value) TryGetValue(List<ValueSlot> valueSlots, Key key)
{
//...
}
//...
}
Unfortunately, this doesn't compile an generates a bunch of errors. I would rather not resort to returning tuples out from the class. Is there a simple way to make this approach work that I am missing? I've been trying to get this to work for nearly a week now...
Polymorphism by return type is not supported by C# yet. Generic type constraint is a hint to the compiler and not making method signatures different.
I'd suggest using Maybe<T> so that you can do this:
public class HashTable<Key, Value>
{
public Maybe<Value> TryGetValue(Key key)
{
(bool result, Value value) = TryGetValue(valueSlots, key);
if (result == true)
{
return new Maybe<Value>(value); // or value.ToMaybe() // with the extension method
}
else
{
return Maybe<Value>.Nothing;
}
}
}
This works regardless of what type the Value is.
Here's the implementation that I use:
public static class MaybeEx
{
public static Maybe<T> ToMaybe<T>(this T value)
{
return new Maybe<T>(value);
}
public static T GetValue<T>(this Maybe<T> m, T #default) => m.HasValue ? m.Value : #default;
public static T GetValue<T>(this Maybe<T> m, Func<T> #default) => m.HasValue ? m.Value : #default();
public static Maybe<U> Select<T, U>(this Maybe<T> m, Func<T, U> k)
{
return m.SelectMany(t => k(t).ToMaybe());
}
public static Maybe<U> SelectMany<T, U>(this Maybe<T> m, Func<T, Maybe<U>> k)
{
if (!m.HasValue)
{
return Maybe<U>.Nothing;
}
return k(m.Value);
}
public static Maybe<V> SelectMany<T, U, V>(this Maybe<T> #this, Func<T, Maybe<U>> k, Func<T, U, V> s)
{
return #this.SelectMany(x => k(x).SelectMany(y => s(x, y).ToMaybe()));
}
}
public class Maybe<T>
{
public class MissingValueException : Exception { }
public readonly static Maybe<T> Nothing = new Maybe<T>();
private T _value;
public T Value
{
get
{
if (!this.HasValue)
{
throw new MissingValueException();
}
return _value;
}
private set
{
_value = value;
}
}
public bool HasValue { get; private set; }
public Maybe()
{
HasValue = false;
}
public Maybe(T value)
{
Value = value;
HasValue = true;
}
public T ValueOrDefault(T #default) => this.HasValue ? this.Value : #default;
public T ValueOrDefault(Func<T> #default) => this.HasValue ? this.Value : #default();
public static implicit operator Maybe<T>(T v)
{
return v.ToMaybe();
}
public override string ToString()
{
return this.HasValue ? this.Value.ToString() : "<null>";
}
public override bool Equals(object obj)
{
if (obj is Maybe<T>)
return Equals((Maybe<T>)obj);
return false;
}
public bool Equals(Maybe<T> obj)
{
if (obj == null) return false;
if (!EqualityComparer<T>.Default.Equals(_value, obj._value)) return false;
if (!EqualityComparer<bool>.Default.Equals(this.HasValue, obj.HasValue)) return false;
return true;
}
public override int GetHashCode()
{
int hash = 0;
hash ^= EqualityComparer<T>.Default.GetHashCode(_value);
hash ^= EqualityComparer<bool>.Default.GetHashCode(this.HasValue);
return hash;
}
public static bool operator ==(Maybe<T> left, Maybe<T> right)
{
if (object.ReferenceEquals(left, null))
{
return object.ReferenceEquals(right, null);
}
return left.Equals(right);
}
public static bool operator !=(Maybe<T> left, Maybe<T> right)
{
return !(left == right);
}
}
I believe what you are looking for is a Maybe Monad. It requires some work. But it is worth it imho. Implementation for Maybe Monad for C# is well described here.
You need to make some compromises to make this work:
public V? GetNullable<V>(Key key) where V : struct, Value
{
(bool result, Value value) = TryGetValue(valueSlots, key);
return result ? (V)value : (V?)null;
}
public V GetValueOrNull<V>(Key key) where V : class, Value
{
(bool result, Value value) = TryGetValue(valueSlots, key);
return result == true ? (V)value : null;
}
You must give different names to the two methods, and provide the type as parameter every time you call them:
var h1 = new HashTable<int, DateTime>(); // Value Type
DateTime? date = h1.GetNullable<DateTime>(1);
var h2 = new HashTable<int, Exception>(); // Reference Type
Exception ex = h2.GetValueOrNull<Exception>(1);
I guess that this defeats the purpose though.

Why I can't convert source type to string even though explicit operator is created?

I have a very simple class:
public class MyCustomBoolean {
private bool _value = false;
public MyCustomBoolean(bool value) {
_value = value;
}
public bool value => _value;
#region casting support
public static explicit operator string(MyCustomBoolean m) {
return m.value.ToString();
}
public static explicit operator bool(MyCustomBoolean m) {
return m.value;
}
#endregion
}
And now, somewhere in my code I try to:
public void someMethod(MyCustomBoolean param) {
string testString = param;
}
The error I keep getting is:
cannot convert source type MyCustomBoolean to type string
I have a few classes handling different types but this one is the only one causing me trouble.
What am I doing wrong here?
You're attempting to use an explicit operator as an implicit one.
The following should work:
public void someMethod(MyCustomBoolean param) {
string testString = (string)param; // explicit cast to string
}
If you wanted to use the code the way it was written, you would need to instead define conversion operators as implicit, like so:
public static implicit operator string(MyCustomBoolean m) {
return m.value.ToString();
}
public static implicit operator bool(MyCustomBoolean m) {
return m.value;
}
At which point, your previous code will work as expected.
public void someMethod(MyCustomBoolean param) {
string testString = param; // implicit cast
}

Implicit (bool) and == operator override - handle if statements correctly

I have a custom class with implement both the == and the implicit for boolean operator.
Is this the correct way to handle all possible, if ==/!= statements and get the expected result?
Like this:
public class Foo
{
public bool Result { get; set; }
public static bool operator ==(bool #bool, Foo foo)
{
return Equals(foo, #bool);
}
public static bool operator !=(bool #bool, Foo foo)
{
return NotEquals(foo, #bool);
}
public static bool operator ==(Foo foo, bool #bool)
{
return Equals(foo, #bool);
}
public static bool operator !=(Foo foo, bool #bool)
{
return NotEquals(foo, #bool);
}
public static bool operator ==(Foo foo, Foo fooB)
{
return Equals(foo, fooB);
}
public static bool operator !=(Foo foo, Foo fooB)
{
return NotEquals(foo, fooB);
}
public static implicit operator bool(Foo foo)
{
try { return foo.Result; }
catch { return false; }
}
private static bool Equals(Foo foo, Foo fooB)
{
if (object.Equals(foo, null))
{
if (object.Equals(fooB, null))
return true;
return false;
}
if (object.Equals(fooB, null))
return false;
return foo.Result == fooB.Result;
}
private static bool NotEquals(Foo foo, Foo fooB)
{
if (object.Equals(foo, null))
{
if (object.Equals(fooB, null))
return false;
return true;
}
if (object.Equals(fooB, null))
return true;
return fooB.Result != foo.Result;
}
private static bool Equals(Foo foo, bool #bool)
{
if (object.Equals(foo, null))
return true;
return #bool == foo.Result;
}
private static bool NotEquals(Foo foo, bool #bool)
{
if (object.Equals(foo, null))
return false;
return #bool != foo.Result;
}
}
I am especially wondering about the fact that its seems you really need to implement overloads for either
if (new Foo() != true)
and
if (true != new Foo())
I think you've written too much code :-)
The following is sufficient:
public class Foo
{
public bool Result { get; set; }
public static implicit operator bool(Foo foo)
{
return !object.ReferenceEquals(foo, null) && foo.Result;
}
}
The compiler will then know how to implicitly convert variables of type Foo into bool. (And null will be converted to false).
So, when you write:
new Foo() == false
The compiler will use the implicit type converter to get a bool value from Foo and then use the standard equality operator for bool.
If we look at the IL that the compiler generates for that expression we find:
newobj instance void FooBool.Foo::.ctor() // new Foo()
call bool FooBool.Foo::op_Implicit(class FooBool.Foo) // implicit operator (Foo => bool)
ldc.i4.0 // false
ceq // equality operator (bool)
Here's a test:
static void Main(string[] args)
{
AssertTrue(new Foo() == false);
AssertTrue(false == new Foo());
AssertFalse(new Foo() != false);
AssertFalse(false != new Foo());
AssertTrue(new Foo { Result = true } == true);
AssertTrue(true == new Foo { Result = true });
AssertFalse(new Foo { Result = true } != true);
AssertFalse(true != new Foo { Result = true });
}
static void AssertTrue(bool value)
{
Console.WriteLine(value ? "ok" : "not ok");
}
static void AssertFalse(bool value)
{
Console.WriteLine(value ? "not ok" : "ok");
}
It prints ok for each test. So this simplified code should fulfill your needs if I understood them correctly.
UPDATE
To allow the equality operator to work for instances of Foo (which may be null):
public static bool operator ==(Foo a, Foo b)
{
if (object.ReferenceEquals(a, b))
{
return true;
}
else if (object.ReferenceEquals(a, null))
{
return !b.Result;
}
else if (object.ReferenceEquals(b, null))
{
return !a.Result;
}
else
{
return a.Result == b.Result;
}
}
You should then also implement the inequality operator:
public static bool operator !=(Foo a, Foo b)
{
return !(a == b);
}
And also override GetHashCode + Equals
public override int GetHashCode()
{
return this.Result ? 1 : 0;
}
public override bool Equals(object obj)
{
if (object.ReferenceEquals(obj, null))
{
return !this.Result;
}
Type t = obj.GetType();
if (t == typeof(Foo))
{
return this.Result == ((Foo)obj).Result;
}
else if (t == typeof(bool))
{
return this.Result == (bool)obj;
}
else
{
return false;
}
}
I think that you explicitly covered all the bases in your code; if needed you must consider the ordering of parameters for the operator so if you want your Equals function to be called for both ordering of parameters what you did is right.
However it looks a bit overkill in the case of comparing Foo to bool since you could simply rely on the implicit conversion. This would allow you to remove all operators between the two types as well as the Equals and NotEquals methods.
What's more, it would avoid some inconsistency in your code regarding the conversion of a null Foo to boolean. When you pass a null Foo to the Equals method it will return true whereas in the implicit conversion a null Foo will return false:
true == (Foo)null; //true
true == Convert.ToBoolean((Foo)null); //false
In closing, here is how i'd write the Foo class, i think it is sufficient:
public class Foo
{
public bool Result { get; set; }
public static bool operator ==(Foo foo, Foo fooB)
{
return Equals(foo, fooB);
}
public static bool operator !=(Foo foo, Foo fooB)
{
return NotEquals(foo, fooB);
}
public static implicit operator bool(Foo foo)
{
return foo == null ? false : foo.Result;
}
private static bool Equals(Foo foo, Foo fooB)
{
if (object.Equals(foo, null))
{
return object.Equals(fooB, null);
}
if (object.Equals(fooB, null))
return false;
return foo.Result == fooB.Result;
}
private static bool NotEquals(Foo foo, Foo fooB)
{
return !Equals(foo, fooB);
}
}

casting datareader value to a to a Nullable variable

I'm trying to run the following code but get a casting error.
How can I rewrite my code to achive the same ?
boolResult= (bool?)dataReader["BOOL_FLAG"] ?? true;
intResult= (int?)dataReader["INT_VALUE"] ?? 0;
Thanks
Use the "IsDbNull" method on the data reader... for example:
bool? result = dataReader.IsDbNull(dataReader["Bool_Flag"]) ? null : (bool)dataReader["Bool_Flag"]
Edit
You'd need to do something akin to:
bool? nullBoolean = null;
you'd have
bool? result = dataReader.IsDbNull(dataReader["Bool_Flag"]) ? nullBoolean : (bool)dataReader["Bool_Flag"]
Consider doing it in a function.
Here's something I used in the past (you can make this an extension method in .net 4):
public static T GetValueOrDefault<T>(SqlDataReader dataReader, System.Enum columnIndex)
{
int index = Convert.ToInt32(columnIndex);
return !dataReader.IsDBNull(index) ? (T)dataReader.GetValue(index) : default(T);
}
Edit
As an extension (not tested, but you get the idea), and using column names instead of index:
public static T GetValueOrDefault<T>(this SqlDataReader dataReader, string columnName)
{
return !dataReader.IsDBNull(dataReader[columnName]) ? (T)dataReader.GetValue(dataReader[columnName]) : default(T);
}
usage:
bool? flag = dataReader.GetValueOrDefault("BOOL_COLUMN");
There's an answer here that might be helpful:
https://stackoverflow.com/a/3308515/1255900
You can use the "as" keyword. Note the caution mentioned in the comments.
nullableBoolResult = dataReader["BOOL_FLAG"] as bool?;
Or, if you are not using nullables, as in your original post:
boolResult = (dataReader["BOOL_FLAG"] as bool?) ?? 0;
bool? boolResult = null;
int? intResult = null;
if (dataReader.IsDBNull(reader.GetOrdinal("BOOL_FLAG")) == false)
{
boolResult = dataReader.GetBoolean(reader.GetOrdinal("BOOL_FLAG"));
}
else
{
boolResult = true;
}
if (dataReader.IsDBNull(reader.GetOrdinal("INT_VALUE")) == false)
{
intResult= dataReader.GetInt32(reader.GetOrdinal("INT_VALUE"));
}
else
{
intResult = 0;
}
I'm sure I found the inspiration for this somewhere around the interweb but I can't seem to find the original source anymore. Anyway, below you find a utility class which allows to define an extension method on DataReader, like this:
public static class DataReaderExtensions
{
public static TResult Get<TResult>(this IDataReader reader, string name)
{
return reader.Get<TResult>(reader.GetOrdinal(name));
}
public static TResult Get<TResult>(this IDataReader reader, int c)
{
return ConvertTo<TResult>.From(reader[c]);
}
}
Usage:
reader.Get<bool?>("columnname")
or
reader.Get<int?>(5)
Here's the enabling utility class:
public static class ConvertTo<T>
{
// 'Factory method delegate', set in the static constructor
public static readonly Func<object, T> From;
static ConvertTo()
{
From = Create(typeof(T));
}
private static Func<object, T> Create(Type type)
{
if (!type.IsValueType) { return ConvertRefType; }
if (type.IsNullableType())
{
return (Func<object, T>)Delegate.CreateDelegate(typeof(Func<object, T>), typeof(ConvertTo<T>).GetMethod("ConvertNullableValueType", BindingFlags.NonPublic | BindingFlags.Static).MakeGenericMethod(new[] { type.GetGenericArguments()[0] }));
}
return ConvertValueType;
}
// ReSharper disable UnusedMember.Local
// (used via reflection!)
private static TElem? ConvertNullableValueType<TElem>(object value) where TElem : struct
{
if (DBNull.Value == value) { return null; }
return (TElem)value;
}
// ReSharper restore UnusedMember.Local
private static T ConvertRefType(object value)
{
if (DBNull.Value != value) { return (T)value; }
return default(T);
}
private static T ConvertValueType(object value)
{
if (DBNull.Value == value)
{
throw new NullReferenceException("Value is DbNull");
}
return (T)value;
}
}
EDIT: makes use of the IsNullableType() extension method defined like so:
public static bool IsNullableType(this Type type)
{
return
(type.IsGenericType && !type.IsGenericTypeDefinition) &&
(typeof (Nullable<>) == type.GetGenericTypeDefinition());
}
Here's my shot at an extension method. Column name semantics and falls back to default(T) when a null is encountered.
public static class DbExtensions
{
public static T ReadAs<T>(this IDataReader reader, string col)
{
object val = reader[col];
if (val is DBNull)
{
// Use the default if the column is null
return default(T);
}
return (T)val;
}
}
Here is the sample usage. Remember that despite string being a reference type, it will still fail to cast to null from a DBNull. The same is true with int?.
public Facility Bind(IDataReader reader)
{
var x = new Facility();
x.ID = reader.ReadAs<Guid>("ID");
x.Name = reader.ReadAs<string>("Name");
x.Capacity = reader.ReadAs<int?>("Capacity");
x.Description = reader.ReadAs<string>("Description");
x.Address = reader.ReadAs<string>("Address");
return x;
}
using extension method:
public static T GetValueOrDefault <T> (this SqlDataReader reader, string column) {
var isDbNull = reader[column] == DBNull.Value;
return !isDbNull ? (T) reader[column] : default (T);
}
Remember that a DBNull is not the same thing as null, so you cannot cast from one to the other. As the other poster said, you can check for DBNull using the IsDBNull() method.
Try this version. It performs some basic conversion and manages default values as well.

How to make your object act as another type when comparing?

I do not remember how to do in C# a comparison of a class against a primitive type.
Example
public class Validate{
... //This is here that we would need to add code
//if I remember to make the object act as a boolean for example
}
...
Validate v = new Validate(...);
if(v==true)
{
...
}
Do you know the name of that and how to do it?
I think you're looking for an implicit type conversion.
Add the following method to your Validate class:
public static implicit operator bool(Validate v)
{
// Logic to determine if v is true or false
return true;
}
To do what you want, you need to override the implicit cast operator:
public class MyObject
{
private int i;
public MyObject(int i)
{
this.i = i;
}
public static implicit operator bool(MyObject o)
{
return o.i % 2 == 0;
}
}
The above example will evaluate to true if the field i is even:
MyObject o1 = new MyObject(1);
MyObject o2 = new MyObject(2);
if (o1)
{
Console.WriteLine("o1");
}
if (o2)
{
Console.WriteLine("o2");
}
The output of the above is o2.
However, it is a bit of a horrible implementation as it leads to confusing code in that you have constructs that read as if (object), which would be unfamiliar to most readers - if (object.IsValid) makes the intention much more clearer.
do you mean operator overloading?
public static bool operator == (Validate v, bool value)
{
return /* some comparison */
// or going off of the other posters answer
return v.IsValid == value;
}
Just add an IsValid property to your Validate class and call that property:
public class Validate
{
public bool IsValid
{
get { [implementation here] }
}
}
...
Validate v = new Validate(...);
if(v.IsValid)
{
...
}
It is possible to create an implicit operator, but it is not advisable to use it this way, because it would make your code hard to follow for other developers.
UPDATE
Okay, just for completeness and education, this is how to do it:
public class Validate
{
public bool IsValid
{
get { [implementation here] }
}
public static implicit operator bool(Validate v)
{
return v.IsValid;
}
}
But again, don't do it. It would make your code pretty hard to follow.

Categories