Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# Implicit Conversion Operator and is/as operator

I'm creating a composite object that I want to be able to be used anywhere one of its wrapped objects could be used. So given the following objects:

public class Foo{}

public class FooWrapper{
    private Foo _foo = new Foo();

    public static implicit operator Foo(FooWrapper wrapper)
    {
       return wrapper._foo;
    }
}

I want to make the following tests pass:

public class ConversionTests
{
     private FooWrapper _uat = new FooWrapper();

     [Test]
     public void Can_Use_Is_Operator()
     {
          Assert.IsTrue(_uat is Foo);
     }

     [Test]
     public void Can_Use_As_Operator()
     {
          Assert.IsTrue(null != _uat as Foo);
     }
}

I've taken a look at the MSDN documentation:
is: http://msdn.microsoft.com/en-us/library/scekt9xw.aspx
as: http://msdn.microsoft.com/en-us/library/cscsdfbt%28v=vs.110%29.aspx

The is documentation implies it is not possible,

Note that the is operator only considers reference conversions, boxing conversions, and unboxing conversions. Other conversions, such as user-defined conversions, are not considered.

Does anyone know if there's a way to construct FooWrapper so is/as conversions will work? Implementing an interface like IConvertible perhaps?

Bonus question: Anyone know why as/is doesn't consider user-defined conversions?

(And sorry if this question is a dup. 'as' and 'is' appear to be stop words here on stackoverflow (as with most search engines), making it quite difficult to search for questions that contain these keywords.)

like image 283
Philip Pittle Avatar asked Dec 20 '22 01:12

Philip Pittle


1 Answers

The is documentation implies it is not possible

The documentation is correct.

Does anyone know if there's a way to construct FooWrapper so is/as conversions will work?

I know. There is not. (Aside from, obviously, making FooWrapper a derived class of Foo.)

The is and as operators are there to tell you what an object really is. Don't try to make them lie.

Implementing an interface like IConvertible perhaps?

Nope.

Anyone know why as/is doesn't consider user-defined conversions?

First, because like I just said, the purpose of is is to tell you what the object really is.

Second, because suppose for the sake of argument the C# compiler team wished to add a new operator, say frob, that has the semantics of an as operator that uses user-defined conversions. x frob Foo gives you back a Foo when x is a FooWrapper. Describe please the IL you would like to see generated for that expression. I think by engaging in this exercise you'll see why it is a hard problem.

like image 146
Eric Lippert Avatar answered Dec 30 '22 10:12

Eric Lippert