Same C# code returns different result on dotnetFramework 1.1 and 2

G

Guest

The following code returns different result when running on dotnetFramework
1.1 and 2.0. For 1.1, it returns "Object". For 2.0, it returns "String". Can
anyone explain to me why? Thanks!

=========================================
using System;

delegate object D();

class A {
public object M() {return "object";}
}

class B:A {
public string M() {return "string";}
}

public class MyClass {
public static void Main() {
B b = new B();
D d = new D(b.M);
Console.WriteLine(d());
}
}
=========================================
 
J

Jon Skeet [C# MVP]

Felix_Jiang said:
The following code returns different result when running on dotnetFramework
1.1 and 2.0. For 1.1, it returns "Object". For 2.0, it returns "String". Can
anyone explain to me why? Thanks!

It's because in C# 1.1, delegate signatures had to match *precisely*,
including return value.

In C# 2.0, delegate signatures can have covariance/contravariance of
return type/parameter types (not necessarily respectively - I can never
remember which way round it is). In other words, if you have a delegate
declared as:

delegate object DoSomething (string x)

and a method

Stream MyMethod (object o)

then you can do:

DoSomething x = new DoSomething (MyMethod);

whereas that would have worked in C# 1.1.

Now, to come to your example - that means that in C# 1.1, only one of
the two methods (the object method) could be chosen, so it was. In C#
2.0, both methods are applicable, so the compiler chooses the most
specific version (in terms of overriding, I believe - I'd need to look
at the spec for the details).

It's an interesting case of breaking backwards compatibility though - I
hadn't come across that before.
 
G

Guest

Jon, thanks for you reply, that really helps. I check the spec and it is
covariance this situation. And I think it will be the same affect for the
contravariance. The code of below demonstrate this.
======================================================
using System;

delegate void D(string s);

class A {
public void M(string s) {Console.WriteLine("string");}
}

class B:A {
public void M(object o) {Console.WriteLine("object");}
}

class Program {
public static void Main() {
B b = new B();
D d = new D(b.M);
d("Message");
}
}
======================================================
The result will be "Object" on 2.0 while "String" on 1.1. I learned from
your thread that for covariance, the compiler chooses the most specific
version. But for contravariance, it seems to be opposite that compiler
chooses the most
general version instead.

Am I correct? Thanks!!!
 
J

Jon Skeet [C# MVP]

Felix_Jiang said:
Jon, thanks for you reply, that really helps. I check the spec and it is
covariance this situation. And I think it will be the same affect for the
contravariance. The code of below demonstrate this.

The result will be "Object" on 2.0 while "String" on 1.1. I learned from
your thread that for covariance, the compiler chooses the most specific
version. But for contravariance, it seems to be opposite that compiler
chooses the most
general version instead.

Am I correct? Thanks!!!

I believe it's not a case of most specific in terms of
parameters/return value - it's returning the one which is a member of
the "most derived" type. However, that's still just a suspicion. I'd
have to check the spec to be sure.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top