Inference, sloppy or good programming practice?

R

Rene

I was experimenting with lambda expressions this afternoon and created the
following snippet of code:

--------------------------------

delegate void Del1(byte b1);
delegate void Del2(int i1);

class FooBar
{
static void DoIt(Del1 del1)
{
}

static void DoIt(Del2 del2)
{
}

static void Main(string[] args)
{
DoIt((x) => System.Console.WriteLine(x.GetType().ToString()));
}
}
--------------------------------

The code above will throw the following compile error: The call is ambiguous
between the following methods or properties: 'Program.DoIt(Del1)' and
'Program.DoIt(Del2)'.

This is all very obvious and very easy to fix but the thing that I want to
point out is that if the snippet of code above only had one "DoIt()" method
then things would compile just fine the way they are. But as soon as you add
the second "DoIt()" overloaded method you get the ambiguity.

So in this example, the lack of explicitly specifying the parameter type on
the lambda expression such as:

DoIt((byte x) => System.Console.WriteLine(x.GetType().ToString()));
DoIt((int x) => System.Console.WriteLine(x.GetType().ToString()));

can cause problems in the future if the class is enhanced (such as adding
the second "DoIt" overloaded method in this case).

Now, here is the problem, supposed that the FooBar class (containing only
*one *DoIt method) was inside a dll that it's widely referenced by many
applications in your company. Also supposed that there are hundreds of
procedures that call the DoIt() method.

Now think about all the code that would break if someone added the second
overloaded DoIt() method to the FooBar class! And all of these problems
caused just because people did not fully qualify the parameter on the lambda
expression.

I realize that my example may be far-out but I am sure you get the point.

So my question to you to ponder is... Is the compiler really doing us a
favor by saving us from typing just a couple of characters?

And by the way, you can run to similar issues due to the delegate
variance/covariance feature and the compiler eagerness to try to guess what
you want to do, see snippet below:

--------------------------------

delegate void MyDel(System.IO.Stream o);

class Program
{
static void Main(string[] args)
{
MyDel d = new MyDel(DoIt);

var ms = new System.IO.MemoryStream();
d(ms);

System.Console.Read();
}

static void DoIt(object o)
{
System.Console.WriteLine("object");
}

// If this method did not exist, MyDel delegate (on
// the Main method) will bind to the DoIt() method
// with the object parameter but when this method
// is added it will bind to this method! Sometimes
// this may not be what you want!
static void DoIt(System.IO.Stream s)
{
System.Console.WriteLine("Stream");
}
}

--------------------------------
 
M

Marc Gravell

So my question to you to ponder is... Is the compiler really doing us a
favor by saving us from typing just a couple of characters?

In the overwhelming majority of cases, yes it is - and in a number of
cases (anonymous types) we *can't* specify the argument. The scenario
you describe is a bit of a corner case, but most variants could be
addressed with generics - i.e. Action<T>. This doesn't help in the
given example, since there is nothing for it to infer the intent from.

In this corner case, perhaps the better answer is: don't introduce a
change that breaks so much code! Perhaps relocate or rename the
method... if it hurts when you move your arm so, then don't do it...

Marc
 
M

Michael C

Rene said:
Now, here is the problem, supposed that the FooBar class (containing only
*one *DoIt method) was inside a dll that it's widely referenced by many
applications in your company. Also supposed that there are hundreds of
procedures that call the DoIt() method.

Can't you run into similar problems now anyway with a simple overload, eg

void DoSomething(object x)
{
//some code
}

then call it like this

DoSomething(null);

then someone adds this and you get an error:

DoSomething(string x)
{
//some code
}

Couldn't this sort of thing happen with all sorts of changes to a dll? (eg
removing a method). I guess you just need to take into account what effect
your changes will have on people who use your dll and make an appropriate
decision. For the number of times this would be a problem (I wouldn't be
suprised if I never encountered this in real life) I think it's a worthwhile
feature.

Michael
 

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