Overloading

  • Thread starter Thread starter Guest
  • Start date Start date
G

Guest

Hi,

Why can I not overload on just the return type?

Say for example.

public int blah(int x)
{
}

and

public double blah(int x)
{
}


Why not, seems quite straight forward to me, why is this a limitation on C#?
 
This is not a limitation of C#, it's not possible in VB.NET too, so I think
it's a IL/CLR limitation. In my opinion it wouldn't make sense to overload a
method only by it's return type. For example, lets say you have an
overloaded method TestMe that returns either a string value or a long value:

string s = TestMe(); ///This is quite straight-forward
object o = TestMe(); ///Would be a problem.


--
Greetz

Jan Tielens
________________________________
Read my weblog: http://weblogs.asp.net/jan
 
Why can I not overload on just the return type?

Say for example.

public int blah(int x)
{
}

and

public double blah(int x)
{
}


Why not, seems quite straight forward to me, why is this a limitation on C#?

Which version would get called here:

blah(5);

?

Or how about:

Console.WriteLine (blah(5));

?

Basically, it introduces an awful lot of ambiguity - and ends up with
an expression without a specific type, which doesn't occur anywhere
else in the language.
 
Good Q in fact.
Lemme take a shot at it:
As I understand, while a function *prototype* describes the return type and
parameters, a function signature *does not include* return types. And
functiona overloading *defines* only functions of different signatures can
be overloaded.


Please correct me if am wrong here.

TIA
Krishnan
 
No, threre's no such restriction at the IL level, but other managed MSFT
languages choose not to support it.

Willy.
 
True, and ILASM also, here's a sample (compile with ilasm).

..assembly extern mscorlib
{
.publickeytoken = (B7 7A 5C 56 19 34 E0 89 )
.ver 1:0:5000:0
}

..assembly invaril
{
.hash algorithm 0x00008004
.ver 0:0:0:1
}

..class private Invariant
{
.method public specialname
instance void .ctor()
{
ret
}

.method public instance int32 Foo()
{
.locals init (int32 local0)
ldc.i4.1
ret //return 1
}

.method public instance int64 Foo()
{
.locals init (int64 local0)
ldc.i4.2
conv.i8
ret // return 2
}
}

..method public static void Execute()
{
.entrypoint
.locals init (class Invariant local0)
newobj instance void Invariant::.ctor()
stloc.0
ldloc.0
//Call int32::Foo()
callvirt instance int32 Invariant::Foo()
call void [mscorlib]System.Console::WriteLine(int32)
ldloc.0
// Call int64::Foo()
callvirt instance int64 Invariant::Foo()
call void [mscorlib]System.Console::WriteLine(int64)
ret
}


Willy.
 
It SHOULD be supported as its technically a DIFFERENT function signiture.

I think its stupid not to support this. Is there any valid reason why this
is not implemented?

I cant think of one.

Willy Denoyette said:
True, and ILASM also, here's a sample (compile with ilasm).

.assembly extern mscorlib
{
.publickeytoken = (B7 7A 5C 56 19 34 E0 89 )
.ver 1:0:5000:0
}

.assembly invaril
{
.hash algorithm 0x00008004
.ver 0:0:0:1
}

.class private Invariant
{
.method public specialname
instance void .ctor()
{
ret
}

.method public instance int32 Foo()
{
.locals init (int32 local0)
ldc.i4.1
ret //return 1
}

.method public instance int64 Foo()
{
.locals init (int64 local0)
ldc.i4.2
conv.i8
ret // return 2
}
}

.method public static void Execute()
{
.entrypoint
.locals init (class Invariant local0)
newobj instance void Invariant::.ctor()
stloc.0
ldloc.0
//Call int32::Foo()
callvirt instance int32 Invariant::Foo()
call void [mscorlib]System.Console::WriteLine(int32)
ldloc.0
// Call int64::Foo()
callvirt instance int64 Invariant::Foo()
call void [mscorlib]System.Console::WriteLine(int64)
ret
}


Willy.

andrew lowe said:
I believe Eiffel supports this
 
Alvin Bruney said:
It SHOULD be supported as its technically a DIFFERENT function signiture.

I think its stupid not to support this. Is there any valid reason why this
is not implemented?

I cant think of one.

Its pretty simple, it heavily complicates the language for very little
benifit. I don't care to have to specify return type on every call, doubt
you would either. Even with defaults it is a messy situation.
Do you have a suggestion as to how to implement it without causing a major
complexity increase?
Willy Denoyette said:
True, and ILASM also, here's a sample (compile with ilasm).

.assembly extern mscorlib
{
.publickeytoken = (B7 7A 5C 56 19 34 E0 89 )
.ver 1:0:5000:0
}

.assembly invaril
{
.hash algorithm 0x00008004
.ver 0:0:0:1
}

.class private Invariant
{
.method public specialname
instance void .ctor()
{
ret
}

.method public instance int32 Foo()
{
.locals init (int32 local0)
ldc.i4.1
ret //return 1
}

.method public instance int64 Foo()
{
.locals init (int64 local0)
ldc.i4.2
conv.i8
ret // return 2
}
}

.method public static void Execute()
{
.entrypoint
.locals init (class Invariant local0)
newobj instance void Invariant::.ctor()
stloc.0
ldloc.0
//Call int32::Foo()
callvirt instance int32 Invariant::Foo()
call void [mscorlib]System.Console::WriteLine(int32)
ldloc.0
// Call int64::Foo()
callvirt instance int64 Invariant::Foo()
call void [mscorlib]System.Console::WriteLine(int64)
ret
}


Willy.

andrew lowe said:
Hi,

Why can I not overload on just the return type?

I believe Eiffel supports this
 
How does it heavily complicate a lanaguage that already supports
overloading.

Dont be stupid. Tard


Daniel O'Connell said:
Alvin Bruney said:
It SHOULD be supported as its technically a DIFFERENT function signiture.

I think its stupid not to support this. Is there any valid reason why this
is not implemented?

I cant think of one.

Its pretty simple, it heavily complicates the language for very little
benifit. I don't care to have to specify return type on every call, doubt
you would either. Even with defaults it is a messy situation.
Do you have a suggestion as to how to implement it without causing a major
complexity increase?
Willy Denoyette said:
True, and ILASM also, here's a sample (compile with ilasm).

.assembly extern mscorlib
{
.publickeytoken = (B7 7A 5C 56 19 34 E0 89 )
.ver 1:0:5000:0
}

.assembly invaril
{
.hash algorithm 0x00008004
.ver 0:0:0:1
}

.class private Invariant
{
.method public specialname
instance void .ctor()
{
ret
}

.method public instance int32 Foo()
{
.locals init (int32 local0)
ldc.i4.1
ret //return 1
}

.method public instance int64 Foo()
{
.locals init (int64 local0)
ldc.i4.2
conv.i8
ret // return 2
}
}

.method public static void Execute()
{
.entrypoint
.locals init (class Invariant local0)
newobj instance void Invariant::.ctor()
stloc.0
ldloc.0
//Call int32::Foo()
callvirt instance int32 Invariant::Foo()
call void [mscorlib]System.Console::WriteLine(int32)
ldloc.0
// Call int64::Foo()
callvirt instance int64 Invariant::Foo()
call void [mscorlib]System.Console::WriteLine(int64)
ret
}


Willy.

"andrew lowe" <andrew dot lowe at geac dot com> wrote in message

Hi,

Why can I not overload on just the return type?

I believe Eiffel supports this
 
You already do have to SPECIFY RETURN TYPES.



Daniel O'Connell said:
Alvin Bruney said:
It SHOULD be supported as its technically a DIFFERENT function signiture.

I think its stupid not to support this. Is there any valid reason why this
is not implemented?

I cant think of one.

Its pretty simple, it heavily complicates the language for very little
benifit. I don't care to have to specify return type on every call, doubt
you would either. Even with defaults it is a messy situation.
Do you have a suggestion as to how to implement it without causing a major
complexity increase?
Willy Denoyette said:
True, and ILASM also, here's a sample (compile with ilasm).

.assembly extern mscorlib
{
.publickeytoken = (B7 7A 5C 56 19 34 E0 89 )
.ver 1:0:5000:0
}

.assembly invaril
{
.hash algorithm 0x00008004
.ver 0:0:0:1
}

.class private Invariant
{
.method public specialname
instance void .ctor()
{
ret
}

.method public instance int32 Foo()
{
.locals init (int32 local0)
ldc.i4.1
ret //return 1
}

.method public instance int64 Foo()
{
.locals init (int64 local0)
ldc.i4.2
conv.i8
ret // return 2
}
}

.method public static void Execute()
{
.entrypoint
.locals init (class Invariant local0)
newobj instance void Invariant::.ctor()
stloc.0
ldloc.0
//Call int32::Foo()
callvirt instance int32 Invariant::Foo()
call void [mscorlib]System.Console::WriteLine(int32)
ldloc.0
// Call int64::Foo()
callvirt instance int64 Invariant::Foo()
call void [mscorlib]System.Console::WriteLine(int64)
ret
}


Willy.

"andrew lowe" <andrew dot lowe at geac dot com> wrote in message

Hi,

Why can I not overload on just the return type?

I believe Eiffel supports this
 
I would like to know how this tard codes C# WITHOUT specifying return types
ROFL

Genius!!


Alvin Bruney said:
You already do have to SPECIFY RETURN TYPES.



Daniel O'Connell said:
Alvin Bruney said:
It SHOULD be supported as its technically a DIFFERENT function signiture.

I think its stupid not to support this. Is there any valid reason why this
is not implemented?

I cant think of one.

Its pretty simple, it heavily complicates the language for very little
benifit. I don't care to have to specify return type on every call, doubt
you would either. Even with defaults it is a messy situation.
Do you have a suggestion as to how to implement it without causing a major
complexity increase?
True, and ILASM also, here's a sample (compile with ilasm).

.assembly extern mscorlib
{
.publickeytoken = (B7 7A 5C 56 19 34 E0 89 )
.ver 1:0:5000:0
}

.assembly invaril
{
.hash algorithm 0x00008004
.ver 0:0:0:1
}

.class private Invariant
{
.method public specialname
instance void .ctor()
{
ret
}

.method public instance int32 Foo()
{
.locals init (int32 local0)
ldc.i4.1
ret //return 1
}

.method public instance int64 Foo()
{
.locals init (int64 local0)
ldc.i4.2
conv.i8
ret // return 2
}
}

.method public static void Execute()
{
.entrypoint
.locals init (class Invariant local0)
newobj instance void Invariant::.ctor()
stloc.0
ldloc.0
//Call int32::Foo()
callvirt instance int32 Invariant::Foo()
call void [mscorlib]System.Console::WriteLine(int32)
ldloc.0
// Call int64::Foo()
callvirt instance int64 Invariant::Foo()
call void [mscorlib]System.Console::WriteLine(int64)
ret
}


Willy.

"andrew lowe" <andrew dot lowe at geac dot com> wrote in message

Hi,

Why can I not overload on just the return type?

I believe Eiffel supports this
 
It SHOULD be supported as its technically a DIFFERENT function signiture.

I think its stupid not to support this. Is there any valid reason why this
is not implemented?

First of because it isn't a different function signature. The return
type doesn't play a role in determining signature.

Secondly, as pointed out elsethread, in case you missed it, calling
a method without an assignment (using the method call in as an
expression in a Console.Writeln argument list is a good one) can't
tell the compiler which overload to invoke.

Oz
 
First of because it isn't a different function signature. The return
type doesn't play a role in determining signature.

That's not entirely true. The framework *does differentiate signature by
return type. However, this feature is not implemented in C# or any other
..NET compatible language for that matter to date. But it is important to
note that the framework does support it and it can be implemented. Compiler
builders/vendors have the right to, and frequently exercise it, to choose
which features of the framework they intend to implement so long as it meets
the minimum requirements set forth by the standardization body (ECMA I
believe).
 
Well it IS logically a DIFFERENT signiture and it SHOULD therefore play a
ROLE in the method signiture.

An Int32 blahFn(Int32) is different from String blahFn(Int32)

Maybe not in todays implementation but it IS different and it SHOULD be
treated as such in the compiler.

There is no logical reason why this is a limitation on C#; just somebody
cant be arsed to have the return type as the signiture, ie., its a half
assed approach.
 
Alvin Bruney said:
I would like to know how this tard codes C# WITHOUT specifying return types
ROFL

Genius!!

Take this class, with return type overloading.

public class Class
{
public string Method(){};
public StringBuilder Method(){};
public Control Method(){};
public Button Method(){};
}

now, on this set of calls, waht are your results?
string stringResult = Method(); //clear, string Method(){} should be called
StringBuilder stringBuilderResult = Method(); // clear, StringBuilder
Method(){} should be called
object objectResult = Method(); // ambigious, any method could be called.
Control controlResult = Method(); // ambigious, should Control Method() or
Button Method() be called?
Method(); //ambigious, any method cound be called;

Your only option would be to change code calling to something akin to(syntax
invented):

object objectResult = string:Method(); //0k
object objectResult = Button:Method(); //0k

As I said, by specifying the return type, in the call not the declaration.
Thats where the complication comes in, it adds extra call syntax. Not to say
I'd be totally adverse to return type overloading if a simple, easy to
follow syntax existed, but only if it didn't result in significant addition
of complexity. Return type overloading beats GetWorkingSet64 imho, but the
additional complexity of the feature may not make it worth it.
Alvin Bruney said:
You already do have to SPECIFY RETURN TYPES.



Daniel O'Connell said:
It SHOULD be supported as its technically a DIFFERENT function signiture.

I think its stupid not to support this. Is there any valid reason
why
this
is not implemented?

I cant think of one.


Its pretty simple, it heavily complicates the language for very little
benifit. I don't care to have to specify return type on every call, doubt
you would either. Even with defaults it is a messy situation.
Do you have a suggestion as to how to implement it without causing a major
complexity increase?

True, and ILASM also, here's a sample (compile with ilasm).

.assembly extern mscorlib
{
.publickeytoken = (B7 7A 5C 56 19 34 E0 89 )
.ver 1:0:5000:0
}

.assembly invaril
{
.hash algorithm 0x00008004
.ver 0:0:0:1
}

.class private Invariant
{
.method public specialname
instance void .ctor()
{
ret
}

.method public instance int32 Foo()
{
.locals init (int32 local0)
ldc.i4.1
ret //return 1
}

.method public instance int64 Foo()
{
.locals init (int64 local0)
ldc.i4.2
conv.i8
ret // return 2
}
}

.method public static void Execute()
{
.entrypoint
.locals init (class Invariant local0)
newobj instance void Invariant::.ctor()
stloc.0
ldloc.0
//Call int32::Foo()
callvirt instance int32 Invariant::Foo()
call void [mscorlib]System.Console::WriteLine(int32)
ldloc.0
// Call int64::Foo()
callvirt instance int64 Invariant::Foo()
call void [mscorlib]System.Console::WriteLine(int64)
ret
}


Willy.

"andrew lowe" <andrew dot lowe at geac dot com> wrote in message

Hi,

Why can I not overload on just the return type?

I believe Eiffel supports this
 
Daniel O'Connell said:
Take this class, with return type overloading.

public class Class
{
public string Method(){};
public StringBuilder Method(){};
public Control Method(){};
public Button Method(){};
}

now, on this set of calls, waht are your results?
string stringResult = Method(); //clear, string Method(){} should be called
StringBuilder stringBuilderResult = Method(); // clear, StringBuilder
Method(){} should be called
object objectResult = Method(); // ambigious, any method could be called.

Call Object then have a specific object method its up to the caller to cast
to the appropriate type.
Control controlResult = Method(); // ambigious, should Control Method() or

Call Control method... Thats what he asked for if its a button, call the
Button one if thats the type tahts specified, no point in calling the Button
one if its a HScroll, no ambiguity
Button Method() be called?
Method(); //ambigious, any method cound be called;

Call the VOID method. No ambiguity.
Your only option would be to change code calling to something akin to(syntax
invented):

object objectResult = string:Method(); //0k
object objectResult = Button:Method(); //0k

As I said, by specifying the return type, in the call not the declaration.
Thats where the complication comes in, it adds extra call syntax. Not to say
I'd be totally adverse to return type overloading if a simple, easy to
follow syntax existed, but only if it didn't result in significant addition
of complexity. Return type overloading beats GetWorkingSet64 imho, but the
additional complexity of the feature may not make it worth it.
Alvin Bruney said:
You already do have to SPECIFY RETURN TYPES.




It SHOULD be supported as its technically a DIFFERENT function
signiture.

I think its stupid not to support this. Is there any valid reason why
this
is not implemented?

I cant think of one.


Its pretty simple, it heavily complicates the language for very little
benifit. I don't care to have to specify return type on every call, doubt
you would either. Even with defaults it is a messy situation.
Do you have a suggestion as to how to implement it without causing a major
complexity increase?

True, and ILASM also, here's a sample (compile with ilasm).

.assembly extern mscorlib
{
.publickeytoken = (B7 7A 5C 56 19 34 E0 89 )
.ver 1:0:5000:0
}

.assembly invaril
{
.hash algorithm 0x00008004
.ver 0:0:0:1
}

.class private Invariant
{
.method public specialname
instance void .ctor()
{
ret
}

.method public instance int32 Foo()
{
.locals init (int32 local0)
ldc.i4.1
ret //return 1
}

.method public instance int64 Foo()
{
.locals init (int64 local0)
ldc.i4.2
conv.i8
ret // return 2
}
}

.method public static void Execute()
{
.entrypoint
.locals init (class Invariant local0)
newobj instance void Invariant::.ctor()
stloc.0
ldloc.0
//Call int32::Foo()
callvirt instance int32 Invariant::Foo()
call void [mscorlib]System.Console::WriteLine(int32)
ldloc.0
// Call int64::Foo()
callvirt instance int64 Invariant::Foo()
call void [mscorlib]System.Console::WriteLine(int64)
ret
}


Willy.

"andrew lowe" <andrew dot lowe at geac dot com> wrote in message

Hi,

Why can I not overload on just the return type?

I believe Eiffel supports this
 
Alvin Bruney said:
called.

Call Object then have a specific object method its up to the caller to cast
to the appropriate type.

There is no method that returns object explicitly. The caller cannot cast to
an arbitrary type, the proper method has to be called, this begins to
introduce alot of guessing in.
or

Call Control method... Thats what he asked for if its a button, call the
Button one if thats the type tahts specified, no point in calling the Button
one if its a HScroll, no ambiguity

Clear ambiguity, Button is a control, it can be assigned to either. If you
require the return type to match you lock in the methods pretty badly,
imagine the boost in casting...
Call the VOID method. No ambiguity.

There is no void method. Some method has to be called

What about these two?
Method().Text = "Something"; //what gets called here?
Method().ToString(); //which method is called here?

 
Yes but when you code, you are specifying using Intellisense what overload
you want, why not use this information?

If he asked for Control Method give him that. if he wants button, give him
that.

Do what he asked

How hard is that?
 
Alvin Bruney said:
Yes but when you code, you are specifying using Intellisense what overload
you want, why not use this information?


If he asked for Control Method give him that. if he wants button, give him
that.

Do what he asked

How hard is that?
Neither the compiler nor users not using the IDE have access to
intellisense. The compiler operates on files, period. Infact in large
projects the compiler isn't even usually invoked from VS during the final
build but instead some other build engine like nant. Some sort of language
syntax would have to exist to perform the call on the proper overload, like
I showed a post or two back. Any implicit defaults would have to be
overridable by language syntax or you severely limit and complicate method
calling(lose the ability to call non-void methods without taking a value,
for example, or to append methods calls on the end of method calls).
 
Back
Top