C# how to make a class that behave like Nullable<T> - c#

Given the code:
public class Filter<T>
{
private bool selected = false;
public bool Selected { get { return selected; } }
private T value;
public T Value { get{ return this.value; } set { this.value = value; selected = true; }
}
public class Test
{
public void filter()
{
DateTime a= new DateTime();
Nullable<DateTime> b = new DateTime(); //Work Like a Charm
Filter<DateTime> c = new DateTime(); //Dosent Work
}
}
In Nullable<T> the new DateTime() can be assigned directly into the variable. In my class, it doesn't work. I want to understand what I'm missing.
I think that is something simple. But I couldn't put it on words to find the answer.

You have to implement implicit operators:
public static implicit operator Filter<T>(T value)
{
return new Filter<T>() { Value = value };
}
An implicit operator will allow you to cast the types without explicitly writing Filter<T> filter = (Filter<T>)value; (explicit cast), but rather only Filter<T> filter = value; (implicit cast).

You need to use an implict conversion operator:
See: Implicit cast operator and the equality operator
This allows you to write code to construct your custom type from another type.

Related

C# boxing/wrapper - custom class act as integer

At the moment i have this class
public class Currency
{
private int _Amount;
public Currency(){... }
public Currency(int amount){_Amount = amount;}
public override string ToString()
{
return _Amount + " Gold.";
}
}
I want this class to have all the functionality of an integer so i can do things like this
Currency curr = new Currency();
Currency curr2 = new Currency(100);
curr = 50;
curr += 50;
curr += curr2;
i found kinda of what i needed here : Integer c++ wrapper
but this is for C++. Can someone tell me how i do this in C#?
public operator Currency() { return _Amount; }
Doesn't work, nor adding implicit/explicit anywhere.
class Currency
{
...
// User-defined conversion from Digit to double
public static implicit operator int(Currency d)
{
return d._Amount;
}
}
See implicit (C# Reference) for more info. The second thing you want to check, is operator overloading.
What you want is to declare it as struct (so it doesn't get boxed/unboxed, nor cant be null unless you mark it Nullable) and have implicit/explicit converters (can be converted without casts)
public struct Currency
public static implicit operator Currency(decimal value)
{
return new Currency(value);
}
public static implicit operator decimal(Currency me)
{
return me.value;
}

Wrapped value extension method / operator

Say I have generic value wrapper:
class Wrapper<T>
{
public T Value { get; set; }
}
And I'd like to use it as listed below (or something like this):
var wrapper = new Wrapper<Target>();
// ...
Target target = wrapper;
How is it possible using implicit operator, extension method or another approach to provide single-place null checking? As one of benefits I want to keep the following code in the single place:
if (wrapper != null)
{
return wrapper.Value;
}
return default(T);
EDIT:
I tried the operator:
public static implicit operator T(Wrapper<T> wrapper)
{
return wrapper.Value ? default(T) : wrapper.Value;
}
It's perfectly works I the way below:
var wrapper = new Wrapper<long>();
long value = wrapper;
But fails on:
var wrapper = new Wrapper<IEnumerable<long>>();
IEnumerable<long> value = wrapper;
Compiler says it is not possible to convert from Wrapper<IEnumerable<long>> to IEnumerable<long>. Any ideas?
You can use an implicit operator:
public static implicit operator T(Wrapper<T> value)
{
return value == null ? default(T) : value.Value;
}
EDIT:
As #ChrisSinclair has pointed out, this doesn't work when T is interface the only solution a can think of is using an extension method like:
public static T SafeGetValue<T>(this Wrapper<T> value)
{
return value == null ? default(T) : value.Value;
}
And then:
IEnumerable<long> value = wrapper.SafeGetValue();
return wrapper.Value ?? default(T);
The null-checking could be done in the generic wrapper itself as follows.
class Wrapper<T>
{
private T _value;
public T Value
{
get
{
return _value ?? default(T);
}
set
{
_value = value;
};
}
}

Determining how an object is cast inside a method with Reflection

How could Reflection be used to determine the ways an object is cast from inside a method?
Example:
Given this type, which can be implicitly cast and assigned as an int, float, or string:
public class VersatileType {
public int intVal = 10;
public float floatVal = 1.5f;
public string stringVal = "words";
// implicit convertions
// ints
public static implicit operator int(VersatileType vt) {
return vt.intVal;
}
public static implicit operator VersatileType(int val) {
VersatileType vt = new VersatileType();
vt.intVal = val;
return vt;
}
// floats
public static implicit operator float(VersatileType vt) {
return vt.floatVal;
}
public static implicit operator VersatileType(float val) {
VersatileType vt = new VersatileType();
vt.floatVal = val;
return vt;
}
// strings
public static implicit operator string(VersatileType vt) {
return vt.stringVal;
}
public static implicit operator VersatileType(string val) {
VersatileType vt = new VersatileType();
vt.stringVal = val;
return vt;
}
}
And the given method which does some implicit casting and assigning:
public VersatileType obj;
public void CastAndAssignObj() {
obj = 0;
string text = obj;
}
Is there a way to use Reflection (or any other process) to determine how "obj" was cast/assigned from inside CastAndassignObj()?
I'd like to end up with a collection containing the Types int and string for the above example.
Many thanks-
Reflection will do you no good here because it will always produce VersatileType and that has 3 properties of type string, int and float reflection won't tell you which one is being used. I think the simplest way to do what you want is either to add a flag (isInt, isFloat, isString) or stop initializing those values so you can say
if (myVersatileType.StringVal != null)
// guess we're a string
You can't use reflection because it does not create different types. There is only one type, which has three values, and only one of those is used.

How can I implicitly convert another struct to my Type?

As it is MyClass x = 120;, is it possible to create such a custom class?
If so, how can I do that?
It's generally considered a bad idea to use implicit operators, as they are, after all, implicit and run behind your back. Debugging code littered with operator overloads is a nightmare. That said, with something like this:
public class Complex
{
public int Real { get; set; }
public int Imaginary { get; set; }
public static implicit operator Complex(int value)
{
Complex x = new Complex();
x.Real = value;
return x;
}
}
you could use:
Complex complex = 10;
or you could ever overload the + operator
public static Complex operator +(Complex cmp, int value)
{
Complex x = new Complex();
x.Real = cmp.Real + value;
x.Imaginary = cmp.Imaginary;
return x;
}
and use code like
complex +=5;
Not sure if this is what you want but you may get there by implementing the implicit operator:
http://msdn.microsoft.com/en-us/library/z5z9kes2(VS.71).aspx
Create an implicit operator:
http://msdn.microsoft.com/en-us/library/z5z9kes2.aspx
For example:
public struct MyStruct // I assume this is what you meant, since you mention struct in your title, but use MyClass in your example.
{
public MyClass(int i) { val = i; }
public int val;
// ...other members
// User-defined conversion from MyStruct to double
public static implicit operator int(MyStruct i)
{
return i.val;
}
// User-defined conversion from double to Digit
public static implicit operator MyStruct(int i)
{
return new MyStruct(i);
}
}
"Is this a good idea?" is debatable. Implicit conversions tend to break accepted standards for programmers; generally not a good idea. But if you're doing some large value library, for example, then it might be a good idea.
yes, here's a short example ...
public struct MyCustomInteger
{
private int val;
private bool isDef;
public bool HasValue { get { return isDef; } }
public int Value { return val; } }
private MyCustomInteger() { }
private MyCustomInteger(int intVal)
{ val = intVal; isDef = true; }
public static MyCustomInteger Make(int intVal)
{ return new MyCustomInteger(intVal); }
public static NullInt = new MyCustomInteger();
public static explicit operator int (MyCustomInteger val)
{ if (!HasValue) throw new ArgumentNullEception();
return Value; }
public static implicit operator MyCustomInteger (int val)
{ return new MyCustomInteger(val); }
}

Handling comparisons with a custom boolean type?

I have a custom object that maps a boolean value from a legacy database to a C# bool (and back again).
My custom bool object looks like this:
public class S2kBool : IUserDefinedType {
public bool Value { get; set; }
public Type SupportedType { get { return typeof(string); } }
// These are the values used to represent booleans in the database
public const string TrueValue = "Y";
public const string FalseValue = "N";
public static S2kBool True {
get { return new S2kBool(true); }
}
public static S2kBool False {
get { return new S2kBool(false); }
}
public S2kBool() : this(false) { }
public S2kBool(bool value) {
this.Value = value;
}
// Called when a property of this type is populated from the database
public void FromSimpleDataType(object value) {
this.Value = value.ToString() == TrueValue;
}
// Called when a property of this type is inserted into the database
public object ToSimpleDataType() {
return this.Value ? TrueValue : FalseValue;
}
}
I would like to be able to do something like this:
public class TestObject {
public S2kBool IsActive = S2kBool.True;
}
TestObject tObj = new TestObject();
if (tObj.IsActive == S2kBool.True) {
// the above would evaluate to true
}
I've seen a few different methods for doing comparisons between objects, but I'm not sure of which one to use.
EDIT: Better yet, would it be possible to do something like the following and have C# treat the S2kBool object as an actual Boolean during comparison? It should also allow comparisons with other S2kBool objects, as well.
if (tObj.IsActive == true) { ... }
There are 2 things to look at; an implicit conversion operator (in S2kBool) to bool, or the true/false operators themselves...
true/false operators (note I prefer the implicit bool conversion myself):
public static bool operator true(S2kBool x) {
return x.Value;
}
public static bool operator false(S2kBool x) {
return !x.Value;
}
then you can use if(tObj.IsActive)
conversion operator:
public static implicit operator bool(S2kBool x) {
return x.Value;
}
works likewise
You might also add a conversion in the other direction:
public static implicit operator S2kBool(bool x)
{
return new S2kBool(x);
}
Then you can assign IsActive = false; etc
Finally, I wonder if this should be an immutable struct? It might be confusing if you expect this to behave like a value. For example, look at the last line here:
TestObject obj1 = new TestObject(),
obj2 = new TestObject();
obj1.IsActive = obj2.IsActive = S2kBool.True;
Console.WriteLine(obj1.IsActive);
Console.WriteLine(obj2.IsActive);
obj1.IsActive.Value = false;
Console.WriteLine(obj1.IsActive);
Console.WriteLine(obj2.IsActive); // what does this print?
This prints false, because both IsActive fields point to the same instance of S2kBool. If that was the intent, then fine. But if it was me, I'd make it immutable (whether class or struct). But since it doesn't really have any state other than a bool, I'd argue that this fits well as a struct.
To be honest, I'm not entirely sure why it is needed at all, when all the functionality could be done via static methods / etc.
Yes, you can do that. You would need to define equality operators and override the Equals method.
Here is an article about operator overloading:
http://www.csharphelp.com/archives/archive135.html
Here is an example of a type with overridden equality operators. You can do the same with assignment and conversion operators, making your type work seamlessly with the built-in bool type. (I took your example, shortened it a bit to keep the example short, and added the equality operators).
public struct S2kBool : IEquatable<bool>
{
public bool Value { get; set; }
public bool Equals(bool other)
{
return Value == other;
}
public override int GetHashCode()
{
return Value.GetHashCode();
}
public static bool operator ==(bool left, S2kBool right)
{
return right.Equals(left);
}
public static bool operator !=(bool left, S2kBool right)
{
return !(left == right);
}
public static bool operator ==(S2kBool left, bool right)
{
return left.Equals(right);
}
public static bool operator !=(S2kBool left, bool right)
{
return !(left == right);
}
}

Categories

Resources