Search code examples
c#implicit-conversionimplicit

non-Static Implicit Operator


Does anyone have an eloquent solution for the lack of support of non-static implicit operators in C#? The following codes shows my current problem:

    class Foo
    {
        public int x { get; set; }
        public int y { get; set; }

        public Foo()
        {                    
        }

        public static implicit operator Foo(Bar b)
        {
            Foo newFoo = new Foo();
            newFoo.y = b.y;
            return newFoo;
        }
    }

    class Bar
    {
        public int y { get; set; }

        public Bar()
        {
        }
    }

    Foo foo = new Foo();
    foo.x = 42;
    Bar bar = new Bar();
    bar.y = 52;
    foo = bar;

    Console.WriteLine(foo.x); // THIS PRINTS 0

Here is the functionality I am looking for:

     public implicit operator Foo(Bar b)
     {
         this.y = b.y;
     }

Solution

  • Fortunately, you can't do this. I say "fortunately" because it's very confusing for the reader. I suggest you just write a method instead, e.g. MergeFrom, so that you're code then reads:

    // Object initializers used for readability.
    Foo foo = new Foo { x = 42 };
    Bar bar = new Bar { y = 52 };
    foo.MergeFrom(bar);
    

    That's much clearer in terms of intent, IMO.

    The assignment operator always sets the value of the variable on the left hand side to the value on the right hand side - possibly via conversion, but never based on the existing value of the variable on the left hand side. That's just how the language works - and you're trying to change that.

    Don't fight against the language: anyone reading the code won't thank you for it. Instead, work with the idioms of the language.

    If you really want to use operators of some kind, you could always overload the + operator:

    public implicit operator +(Foo lhs, Bar rhs)
    {
        return new Foo { x = lhs.x, y = rhs.y };
    }
    

    Then you can use:

    foo += bar;
    

    ... which again is clearer that the final value of foo depends on the existing value.