Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

implicit operator on generic types

Is there anything wrong with using an implicit operator like the following:

//linqpad c# program example
void Main()
{
    var testObject = new MyClass<int>() { Value = 1 };

    var add = 10 + testObject; //implicit conversion to int here
    add.Dump(); // 11
}

class MyClass<T>
{
    public T Value { get; set; }
    public static implicit operator T (MyClass<T> myClassToConvert)
    {
        return myClassToConvert.Value;
    }
}

I was thinking I could treat as instance of the object as a value type this way, but seeing as I've never seen an example of this I thought maybe there was a reason not to do something like this that someone could point out?

In my actual code I was thinking of doing this as part of a data abstraction layer, so that I could return objects with information describing the underlying data, but allow the logic code to treat it as a value type when all it needs to know about is the value, and at the same time keep it all nice and type safe with the generics.

like image 900
asawyer Avatar asked Sep 29 '10 15:09

asawyer


People also ask

What is an implicit operator in C#?

The Implicit Operator According to MSDN, an implicit keyword is used to declare an implicit user-defined type conversion operator. In other words, this gives the power to your C# class, which can accepts any reasonably convertible data type without type casting.

Which operator can be used to do type conversion in C#?

Use the operator and implicit or explicit keywords to define an implicit or explicit conversion, respectively. The type that defines a conversion must be either a source type or a target type of that conversion. A conversion between two user-defined types can be defined in either of the two types.

Is it possible to inherit from a generic type?

You can't inherit from a Generic type argument. C# is strictly typed language. All types and inheritance hierarchy must be known at compile time. . Net generics are way different from C++ templates.

How do you find a generic type?

Use the IsGenericType property to determine whether the type is generic, and use the IsGenericTypeDefinition property to determine whether the type is a generic type definition. Get an array that contains the generic type arguments, using the GetGenericArguments method.


1 Answers

If all of the following are true:

  • all possible values of your MyClass<T> type (including null if it’s not a value type!) map to a valid value of T

  • the implicit operator never throws (not even for null!)

  • the implicit conversion makes semantic sense and is not confusing to the client programmer

then there is nothing wrong with this. Of course you could do any of these three things, but it would be bad design. In particular, an implicit operator that throws can be very hard to debug because the place where it is called doesn’t say that it is being called.

For example, consider that T? has no implicit conversion to T (where T is, of course, a value type). If there was such an implicit operator, it would have to throw when the T? is null, as there is no obvious value to convert null to that would make sense for any value type T.


Let me give an example where I had trouble debugging an issue where the implicit operator threw:

public string Foo()
{
    return some_condition ? GetSomething() : null;
}

Here, GetSomething returned something of a type I wrote which has a user-defined implicit conversion to string. I made absolutely sure that GetSomething could never return null, and yet I got a NullReferenceException! Why? Because the above code is not equivalent to

return some_condition ? (string)GetSomething() : (string)null;

but to

return (string)(some_condition ? GetSomething() : (Something)null);

Now you can see where the null came from!

like image 99
Timwi Avatar answered Oct 14 '22 08:10

Timwi