Hi,
this is similar to a problem discussed here: [link:cs.hubfs.net]. Basically, this is a limitation in the F# language, which allows using ":?>" operator only when the target type (interface d in your case) is inherited from the source type (interface c in your case). This is unnecessary limitation for interfaces (but it is useful for classes), so the limitation for interfaces will be probably removed in a future version.

In the meantime you can use following:

1
2
3
4
 
let dynamic_cast o = (box o) :?> 'a

let x5 : d = dynamic_cast x
By on 11/20/2007 3:16 AM ()

Thank you for the explanation;

but I do not understand "but it is useful for classes" of the following sentence:

> This is unnecessary limitation for interfaces (but it is useful for classes),

Could you explain to me more concretely?

In fact, the reliance on the dynamic type test already looks a limitation.

I thought that the type system could deduce

the fact that x implements the interface d.
Best regards,

keiko

By on 11/20/2007 7:32 AM ()

Hi,
I did a few mental steps without explaining them, so let me clarify this.

Object expressions in F# are really (currntly) intended only for implementing a single interface type, which means that the type of the expression is just this interface type. You cannot for example add new members, because the return type is the interface that you're impementing and there wouldn't be any (reasonable) way for accessing the members. I'm a bit surprised that the syntax allows implementing multiple interfaces, because as far as I know this isn't currently the intended use (but I think that it makes very good sense and that it would be nice to support this in the future by returning a type that implements both interfaces - this is probably a bit difficult to implement technicall in .NET, but I think it should be possible). So that's I think why it doesn't work without dynamic tests.

The restriction for classes is sometimes useful - for example let's say you have a base class A, class B inherited from A and some completely unrelated class C. When you have instances a, b and c the compiler will do the following:

1
2
3
4
 
a :?> B // allowed because B inherits from A so 'a' can be instance of B upcasted to type A
c :?> B // not allowed because instance of type C cannot contain a value that 
// could be casted to B (because .NET supports single implementation inheritance)

However - these restrictons don't work well or inerface types, because a class can implement multiple intrfaces.

By on 11/20/2007 1:47 PM ()

On the object expression question, see

[link:research.microsoft.com], where it says this:

Objects created via object expressions can also support multiple interfaces.. The syntax is:

1
2
3
4
5
6
7
8
{ new <CLASS-OR-INTERFACE-TYPE> with <OVERRIDES>

     interface <INTERFACE-TYPE> with <OVERRIDES>

     ...

     interface <INTERFACE-TYPE> with <OVERRIDES> }

e.g.,

1
2
3
4
5
{ new Object()
        with Finalize() = cleanupFunction(false);

      interface IDisposable 
        with Dispose() = cleanupFunction(true);  } 

The interfaces are not part of the type of the object expression but can be revealed through type tests.

By on 11/20/2007 5:12 PM ()
IntelliFactory Offices Copyright (c) 2011-2012 IntelliFactory. All rights reserved.
Home | Products | Consulting | Trainings | Blogs | Jobs | Contact Us | Terms of Use | Privacy Policy | Cookie Policy
Built with WebSharper