views:

174

answers:

4

In Scala, I can define structural types as follows:

type Pressable = { def press(): Unit }

This means that I can define a function or method which takes as an argument something that is Pressable, like this:

def foo(i: Pressable) { // etc.

The object which I pass to this function must have defined for it a method called press() that matches the type signature defined in the type - takes no arguments, returns Unit (Scala's version of void).

I can even use the structural type inline:

def foo(i: { def press(): Unit }) { // etc.

It basically allows the programmer to have all the benefits of duck typing while still having the benefit of compile-time type checking.

Does C# have something similar? I've Googled but can't find anything, but I'm not familiar with C# in any depth. If there aren't, are there any plans to add this?

+3  A: 

No, and no plans that I know of. Only named (rather than structural) subtyping (e.g. interfaces).

(Others may want to see also

http://en.wikipedia.org/wiki/Nominative_type_system

http://en.wikipedia.org/wiki/Structural_type_system

)

(A few people may point out some exotic corner cases, like the foreach statement using structural typing for GetEnumerator, but this is the exception rather than the rule.)

Brian
Another case would be a generic type argument with a default constructor constraint.
Michael Petito
A: 
interface Pressable { void press(); }

void foo(Pressable i) {

sorry, no inlining.

Andrey
That's not structural.
Brian
@Brian whats the difference then? my example fits initial sample 100%
Andrey
It's nominative. A concrete type has to declare itself to be a subtype of `IPressable` to be used by `foo`. With structural subtyping, a concrete type need not declare itself to be `IPressable`, it just needs to have the right method signature available. That's the essential difference between named/nominative typing and structural subtyping.
Brian
The difference is that you'd have to define new interfaces for every structure you care to match and your types would have to implement all of these interfaces (because the match is by name).
Michael Petito
+1  A: 

There isn't a way to define structural types that has a particular function. There is a library that adds duck typing support to C# that can be found here.

This is the example from Duck Typing project. Please note the the duck typing happens at runtime and can fail. It is my understanding also that this library generates proxies for the types that are duck typed, which is far cry from the elegant compile-time support that is enjoyed in Scala. This is most likely as good as it gets with this generation of C#.

public interface ICanAdd
{
    int Add(int x, int y);
}

// Note that MyAdder does NOT implement ICanAdd, 
// but it does define an Add method like the one in ICanAdd:
public class MyAdder
{
    public int Add(int x, int y)
    {
        return x + y;
    }
}

public class Program
{
    void Main()
    {
        MyAdder myAdder = new MyAdder();

        // Even though ICanAdd is not implemented by MyAdder, 
        // we can duck cast it because it implements all the members:
        ICanAdd adder = DuckTyping.Cast<ICanAdd>(myAdder);

        // Now we can call adder as you would any ICanAdd object.
        // Transparently, this call is being forwarded to myAdder.
        int sum = adder.Add(2, 2);
    }
}

This is the C# way of achieving the same thing using the good ol boring interfaces.

interface IPressable {
  void Press();
}

class Foo {
 void Bar(IPressable pressable) {
    pressable.Press();
 }
}

class Thingy : IPressable, IPushable, etc {
 public void Press() {
 }
}

static class Program {
 public static void Main() {
  pressable = new Thingy();
  new Foo().Bar(pressable);
 }
}
Igor Zevaka
Surely the duck-casting library can fail at runtime if the method is not there? Just want to be clear that it's not compile-time checking.
Brian
Obviously. I ll add a comment in bold that it happens at runtime and can fail.
Igor Zevaka
+3  A: 

As others noted, this is not really available in .NET (as this is more a matter of the runtime than a language). However, .NET 4.0 supports similar thing for imported COM interfaces and I believe this could be used for implementing structural typing for .NET. See this blog post:

I didn't try playing with this myself yet, but I think it might enable compiler authors to write languages with structural typing for .NET. (The idea is that you (or a compiler) would define an interface behind the scene, but it would work, because the interfaces would be treated as equivalent thanks to the COM equivalence feature).

Also, C# 4.0 supports the dynamic keyword which, I think, could be interpreted as a structural typing (with no static type checking). The keyword allows you to call methods on any object without knowning (at compile-time) whether the object will have the required methods. This is essentially the same thing as the "Duck typing" project mentioned by Igor (but that's, of course, not a proper structural typing).

Tomas Petricek
that's a bad hack and should not be used!
Ion Todirel
No static type checking defeats the purpose of structural typing, IMO.
musicfreak
@Ion: definitely :-), but maybe it could be used by some compilers @musicfreak: Yes, I agree, but maybe it's better than nothing.
Tomas Petricek
@Tomas: isn't this (http://tomasp.net/blog/cannot-return-anonymous-type-from-method.aspx ) also kind of a very limited, poor-man's structural typing? Without static type checking and also without methods, but still. It's not applicable to the OP's question of course.
Mauricio Scheffer
@Marucio: Yeah, I think it is. Anonymous types use structural typing, but only locally. I guess that if it worked globally, then it would be proper structural typing, but that cannot work (because two equivalent anonymous types from different assemblies are treated as different types - though the trick with COM in .NET 4.0 may be a workaround for that :-)).
Tomas Petricek