views:

784

answers:

3

I don't mean dynamic casting in the sense of casting a lower interface or base class to a more derived class, I mean taking an interface definition that I've created, and then dynamically casting to that interface a different object NOT derived from that interface but supporting all the calls.

For example,

interface IMyInterface
{
   bool Visible
   {
      get;
   }
}

TextBox myTextBox = new TextBox();
IMyInterface i = (dynamic<IMyInterface>)myTextBox;

This could be achieved at compile time for known types, and runtime for instances declared with dynamic. The interface definition is known, as is the type (in this example) so the compiler can determine if the object supports the calls defined by the interface and perform some magic for us to have the cast.

My guess is that this is not supported in C#4 (I was unable to find a reference to it), but I'd like to know for sure. And if it isn't, I'd like to discuss if it should be included in a future variant of the language or not, and the reasons for and against. To me, it seems like a nice addition to enable greater polymorphism in code without having to create whole new types to wrap existing framework types.

Update
Lest someone accuse me of plagiarism, I was not aware of Jon Skeet having already proposed this. However, nice to know we thought of exceedingly similar syntax, which suggests it might be intuitive at least. Meanwhile, "have an original idea" remains on my bucket list for another day.

+3  A: 

I think Jon Skeet has had such a proposal (http://msmvps.com/blogs/jon_skeet/archive/2008/10/30/c-4-0-dynamic-lt-t-gt.aspx), but so far, I haven't heard that C# 4.0 is going to have it.

Mehrdad Afshari
Dammit. One day I'll have an original idea. :(
Jeff Yates
+2  A: 

I think that's problematic. You are introducing coupling between two classes which are not coupled.

Consider the following code.

public interface IFoo
{
   int MethodA();
   int MethodB();
}

public class Bar
{
   int MethodA();
   int MethodB();
}

public class SomeClass
{
   int MethodFoo(IFoo someFoo);
}

should this then be legal?

int blah = someClass.MethodFoo((dynamic<IFoo>)bar);

It seems like it should be legal, because the compiler should be able to dynamically type bar as something that implements IFoo.

However, at this point you are coupling IFoo and Bar through a call in a completely separate part of your code.

If you edit Bar because it no longer needs MethodB, suddenly someClass.MethodFood doesn't work anymore, even though Bar and IFoo are not related.

In the same way, if you add MethodC() to IFoo, your code would break again, even though IFoo and Bar are ostensibly not related.

The fact is, although this would be useful in select cases where there are similarities amongst objects that you do not control, there is a reason that interfaces have to be explicitly attached to objects, and the reason is so that the compiler can guarantee that the object implements it.

But the OP says explicitly marking it as *dynamic*. If this breaks consistency. dynamic o = new object(); o.InvalidMethod(); should also do.
Mehrdad Afshari
In using the dynamic tag, you're simply highlighting the fact that you should couple the objects. Why create a special dynamic tag, when using the already existing 'interface-methodology' works?Perhaps you could clarify your comment, I'm not sure I understand it.
The example you gave is not correct as you are not explicitly requesting dynamic typing. I explicitly request dynamic typing, which, if both types are known at compile time, the compiler can use to flag up a type mismatch error, or if at runtime, the DLR can determine if the calls exist, just as it must do for the individual calls it already marshalls in the existing dynamic type mechanism of C# 4.
Jeff Yates
In addition, the dynamic tag already exist in C#4 as part of the dynamic type handling where the compiler doesn't know if an object implements a particular call. It is instead worked out at runtime. My suggestion is merely an extension to that existing system.
Jeff Yates
I'm not certain, I'm dead set against having such an option, but I am set against using it. It seems to me like explicitly stating your couplings (by declaring "Bar : IFoo") is clearer. If there is no call to Bar.MethodB(), then I should be able to remove MethodB(). Bar is not implementing an interface, so it isn't bound to implement the method, and MethodB is never called, so it shouldn't break the code. But we would then find after deleting it that Bar IS bound to implement it, except it is being coupled to the interface in execution code rather than in class definition code.
I'm not certain that was clear. (I'm certain it was not).Coupling should be defined IN the class definition. It implements IFoo because it is Bar : IFoo.Coupling should NOT be introduced in code later on by saying "By the way, Bar is an IFoo, deal with it."through the dynamic keyword.Keep in mind, when I say "should" that's just my opinion.
Dynamic languages have been around for a long time and the changes to C#4 are intended to improve interoperability with those languages and also COM. It's not knew to late-bind rather than early-bind - C# just hasn't had nice first class support for it until C#4. Your objections to dynamic typing in C# are fair, but they don't answer my question, which assumes the decision is already made to include dynamic typing. My request is to expand that to a whole interface rather than just a single method, which is not breaking the existing rules as far as I am aware.
Jeff Yates
I think you (the coder) are incurring a lot of risk by declaring that someobject will always implement someinterface. When you dynamically say someobject.MethodDoesntExistYet(). You are making a promise about that single object. When you dynamically tie it to an interface, you are making promises about BOTH the object and the interface. But I see your point.
I understand the risks, but that's the risk you take in dynamic late-binding. Assuming we have that, there is value in dynamically asking for a particular set of methods to be available on a type. If the runtime tells you that the type does not support that interface of methods, you can act accordingly, just as you would if you asked for a single method.
Jeff Yates
I think we're at an impasse, because you understand what I mean, but don't agree, and you did an excellent job of describing what you mean, but ultimately, although it would be useful, I think it runs the risk of spaghetti code. Then again, so does GOTO but they are still valid. So I agree that such a construct would be very useful, but there would have to be best practices in place to ensure that the coders know that there are external restrictions on what they can and can't change in their classes/interface declarations.
+1  A: 

There is no need for C# to support this, as it can be implemented very cleanly as library.

I've seen three or four separate implementations (I started writing one myself before I found them). Here's the most thorough treatment I've seen:

http://bartdesmet.net/blogs/bart/archive/2008/11/10/introducing-the-c-ducktaper-bridging-the-dynamic-world-with-the-static-world.aspx

It will probably be even easier to implement once the DLR is integrated into the runtime.

Because the wrapper/forwarder class for a given interface can be generated once and then cached, and then a given object of unknown type can be wrapped once, there is a lot of scope for caching of call sites, etc. so the performance should be excellent.

In contrast, I think the dynamic keyword, which is a language feature, and a hugely complex one, is an unnecessary and potentially disastrous digression, shoe-horned into a language that previously had a very clear static typing philosophy, which gave it an obvious direction for future improvement. They should have stuck to that and made the type inference work better and better until typing became more invisible. There are so many areas where they could evolve the language, without breaking existing programs, and yet they don't, simply due to resource constraints (e.g. the reason var can't be used in more places is because they would have to rewrite the compiler and they don't have time).

They are still doing good stuff in C# 4.0 (the variance features) but there is so much else that could be to be done to make the type system smarter, more automatic, more powerful at detecting problems at compile time. Instead, we're essentially getting a gimmick.

Daniel Earwicker
I think the motivations for including the dynamic keyword are more than acceptable considering the hell that is interoperability right now. By using the dynamic keyword, it maintains the statically typed nature of the language and forces developers to think about what they're writing and be implicit in their use of dynamic types - as opposed to say, using the object keyword for dynamically typed objects. I think making typing invisible is exactly what you don't want in a statically typed language. (var in multiple places is more than a compiler re-write, it's possible a language semantics...
Jeff Yates
... change as you'd have to include rules on who gets to assign a variable first (so that the type can be correctly inferred). I certainly don't see dynamic as a gimmick - it's a huge step forward for things like COM interop and a nice way of providing dynamic language support in a statically typed language. The compiler does huge amounts of work regarding type usage, but I'm not sure doing more is a good idea as it can lead to lazy development of bad code. The compiler should be enforcing rules, not giving us ways to ignore them.
Jeff Yates
It's _one_ way of providing dynamic language support in a statically typed language; in my view (already explained) it's the wrong one. Re: enforcing rules, I'm only talking about the kind of inference done by languages like Haskell. The rules are enforced, and therefore cannot be ignored. However, the need to say the same thing *twice* is reduced. That's got to be a good thing.
Daniel Earwicker