MarioDS
MarioDS

Reputation: 13073

Why does the "as" operator not use an implicit conversion operator in C#?

I have defined implicit string conversion from/to a certain type in C# (dummy code):

public class MyType
{
    public string Value { get; set; }

    public static implicit operator MyType(string fromString)
    {
        return new MyType { Value = fromString };
    }

    public static implicit operator string(MyType myType)
    {
        return myType.Value;
    }
}

Somewhere in external library code, an instance of MyType is passed to a method, as an object parameter. Part of that method looks like something along these lines:

private void Foo(object value)
{
    // ... code omitted
    var bar = value as string // note that value is an instance of MyType at runtime
    if(bar != null) // false, cast fails
    {
       // ... code omitted
    }
}

Why does the cast not use the implicit converter? I thought the whole point of these was to make casting and transparent usage possible?

Would this work if MyType had an explicit converter instead? If so, (how) can I have both?

By the way, the cast definitely works if the type is known at compile-time. Is this because operators are static? Is there something like non-static conversion operators?

P.S. I'm actually most interested in the differences between compile-time behaviour and runtime behaviour, so I've a follow-up question: Why are implicit type conversion operators not dynamically usable at runtime in C#?

Upvotes: 21

Views: 2871

Answers (4)

Sriram Sakthivel
Sriram Sakthivel

Reputation: 73502

as keyword doesn't considers the user defined operators. You need to use a cast operator instead. Related article from Eric Lippert

In your case both explicit and implicit operators can't help you as you're trying to cast from object to string not from MyType to string. For user defined conversion operators to work, compile time type of the instance to be of type MyType instead of object. Because there is no conversion exist from object to string but from MyType to string.

Upvotes: 10

IMil
IMil

Reputation: 1400

Imagine that an implicit conversion operator would have to get called. In this case, any call

var castObj = rawObj as SomeType;

would require the .NET runtime to use reflection in order to determine whether the "rawObj" object has a conversion operator. Obviously, this would be much more computationally expensive than just to check if the object is of type SomeType or its subtype. Better to have a fast and predictable operator than a more versatile, but much slower one.

Upvotes: 2

Matthew Watson
Matthew Watson

Reputation: 109852

The C# language Specification explicitly mentions this in the documentation for as:

Note that some conversions, such as user defined conversions, are not possible with the as operator and should instead be performed using cast expressions.

So you have to cast it.

Upvotes: 9

Jon Skeet
Jon Skeet

Reputation: 1503789

Why does the soft cast not use the implicit converter?

Well, that's the way the language is specified, basically. From the C# 5 specification section 7.10.11:

If the compile-time type of E is not dynamic, the operation E as T produces the same result as

E is T ? (T)(E) : (T)null

except that E is only evaluated once.

[...]

Note that some conversions, such as user defined conversions, are not possible with the as operator and should instead be performed using cast expressions.

Upvotes: 20

Related Questions