tags:

views:

71

answers:

1

How would you implement the Cast<T>() method of linq on single objects?

Here's the scenario:

public interface IFoo
{
    String Message { get; set; }
}

public class Foo : IFoo
{
    IFoo.Message { get; set; }
    internal SecretMessage { get; set; } // secrets are internal to the assembly
}

internal class Fubar
{
    public IFoo Foo { get; set; }
}

I'd like to be able to do...

fubarInstance.Foo.Cast<Foo>.SecretMessage = "";

Instead of...

((Foo)fubarInstance.Foo).SecretMessage = "";
+5  A: 

Why? Why not use the casting syntax which is familiar to every C# programmer on the planet? Unless you can think of very definite benefits to performing the cast in a method, stick to the built-in mechanism.

If you really want to, you could write:

public static T Cast<T>(this object o) {
    return (T) o;
}

... but I would strongly recommend you not to do it.

Jon Skeet
I think my suggestion looks slicker. And if programmers know linq; the chances of them understanding how to use the method - seeing it show up in intellisense - will be good.
roosteronacid
I agree with Jon. Such an extension method increases the amount of WTF per minutes in your code.
Steven
@roosteronacid: A programmer who knows LINQ expects `Cast` to work on collections, not single objects. Also, if your type is *already* a collection (and you're trying to cast it to something else) then the reader will need to work out what kind of cast will actually be called.
Jon Skeet
I like the idea of .Cast<T>() for the same reasons I prefer method chaining over LINQs "from x in w...". Its intuitive that the target type is right from the source type.
Nappy
@Jon: My example-code in my question is a bit simple. I am in a position where I'm doing three casts in one line of code. Using my proposed method; that line looks a lot cleaner to me. I guess you could argue that I could split the 3-times cast up into separate variables, but imho that would look just as "noisy". Imho this looks kinda nice: `instance.Cast<OtherClass>().Foo.Cast<IWiden>().Integer.Cast<Enum>()`... and it's a one-liner.
roosteronacid
@roosteronacid: Hmmm. While I do see the advantage of a fluent interface, I would *at least* consider renaming it to "SingleCast" or something else to distinguish it from the LINQ method.
Jon Skeet
My naming proposal: `To<T>()` / `As<T>()`
Nappy
@Jon: I don't understand why you want to distinguish it from the linq method. Both methods does the same thing, only the built-in casts a collection. Whatever happened to abstracting functionality?
roosteronacid
@roosteronacid: No, they don't do the same thing. One casts the object you call it on, the other casts *each element* of the object you call it on. That's a huge difference.
Jon Skeet
Perhaps a bit devils advocate'ish: but what about `ToString()`? - the same name on a wide array of objects, and depending on which object you call it on, you get a different result. It's an abstraction of functionality, just as my Object extension method is.
roosteronacid
@roosteronacid: But that's up to the *execution time* type... and it's always meant to give a string representation of the object. In other words, different implementations will behave differently, but performing the same basic function. I'd argue you're performing a significantly different kind of conversion here.
Jon Skeet
@Jon: What I'm saying is this: I don't need to know the implementation of X method. All I need to know is what it does. And I can't imagine the scenario where the reader won't know what type he/she is calling Cast on. Therefore I don't see that the reader won't know which method is actually getting called--linq's Cast method on collections or my Cast method on a single object.
roosteronacid
@roosteronacid: So do you give all your methods the same name, even if they do different things? :) I'm saying that the behaviour of these two methods is sufficiently different that it makes sense to give them different names.
Jon Skeet
That's where we disagree--I don't see casting a collection or a single object through an extension method as two radically different things. I'm more generic (get it? :P )
roosteronacid
I guess we'll have to agree to disagree then... see what whoever's reading the code next thinks.
Jon Skeet