views:

96

answers:

3

Given a couple types like this:

interface I {}
class C : I {}

How can I do a static type cast? By this I mean: how can I change its type in a way that gets checked at compile time?

In C++ you can do static_cast<I*>(c). In C# the best I can do is create a temporary variable of the alternate type and try to assign it:

var c = new C();
I i = c;  // statically checked

But this prevents fluent programming. I have to create a new variable just to do the type check. So I've settled on something like this:

class C : I
{
    public I I { get { return this; } }
}

Now I can statically convert C to I by just calling c.I.

Is there a better way to do this in C#?

(In case anyone's wondering why I want to do this, it's because I use explicit interface implementations, and calling one of those from within another member function requires a cast to the interface type first, otherwise the compiler can't find the method.)

UPDATE

Another option I came up with is an object extension:

public static class ObjectExtensions
{
    [DebuggerStepThrough]
    public static T StaticTo<T>(this T o)
    {
        return o;
    }
}

So ((I)c).Doit() could also be c.StaticTo<I>().Doit(). Hmm...probably will still stick with the simple cast. Figured I'd post this other option anyway.

+1  A: 
var c = new C(); 
I i = c;  // statically checked

equals to

I i = new C();
Danny Chen
Correct. Unfortunately, that doesn't address my question.
Scott Bilas
+5  A: 

Simply cast it:

(I)c

Edit Example:

var c = new C();

((I)c).MethodOnI();
Maxem
(facepalm)..well that was obvious, why didn't I try that? Ugly but it works. Thanks. :)
Scott Bilas
Now that I think about it more, there is one small way that the compiler will skip the static type check. Say you start with an Object. It can be cast to anything with no errors, whereas the extension method `StaticTo<T>` I just added above to the question would catch such a bad cast. A minor point.
Scott Bilas
+2  A: 

If you're really just looking for a way to see if an object implements a specific type, you should use as.

I i = whatever as i;
if (i == null) // It wasn't

Otherwise, you just cast it. (There aren't really multiple types of casting in .NET like there are in C++ -- unless you get deeper than most people need to, but then it's more about WeakReference and such things.)

I i = (I)c;

If you're just looking for a convenient way to turn anything implementing I into an I, then you could use an extension method or something similar.

public static I ToI(this I @this)
{
    return @this;
}
John Fisher