Coffeehouse Thread

34 posts

Why does C# not support this?

Back to Forum: Coffeehouse
  • User profile image
    Maddus Mattus

    public class Worker { 
    public int DoWork() { return 10; } 
    public string DoWork() { return "Work"; } 
    } 
    public class Program 
    { 
    public Program() 
    { 
    Worker worker = new Worker; 
    int workInt = worker.DoWork(); 
    string workString = worker.DoWork(); 
    }} 

     

     I know I know

     

    But in 2010 a compiler should be intelligent enough, right?

     

    Maybe I should put this in the c# 5.0 wishlist.

  • User profile image
    Massif

    Well what would

     

    var whatAmI = worker.DoWork();

     

    Do? and of course what would:

     

    worker.DoWork();

     

    Do when we don't care about the return?

     

    I also don't like it because it doesn't seem properly polymorphic to me, as the return type is clearly related to what the function does, and now the identically named functions are clearly doing something different. But that's just me.

  • User profile image
    Maddus Mattus

    Massif said:

    Well what would

     

    var whatAmI = worker.DoWork();

     

    Do? and of course what would:

     

    worker.DoWork();

     

    Do when we don't care about the return?

     

    I also don't like it because it doesn't seem properly polymorphic to me, as the return type is clearly related to what the function does, and now the identically named functions are clearly doing something different. But that's just me.

    I hate var's

     

    they are for lazy programmers Smiley

     

    and worker.DoWork() would not be possible, because DoWork has a return type. Ignoring the return is not 'first class' as Erik would call it Smiley

  • User profile image
    Massif

    Maddus Mattus said:
    Massif said:
    *snip*

    I hate var's

     

    they are for lazy programmers Smiley

     

    and worker.DoWork() would not be possible, because DoWork has a return type. Ignoring the return is not 'first class' as Erik would call it Smiley

    Or of course:

     

    ojbect thing = worker.DoWork();

     

    And, if you have a class A which inherits from B which inherits from C (and DoWork implementations returning As and Bs) what does:

     

    C wtf = worker.DoWork();

     

    Resolve as? It'd just be too confusing for us humble programmers.

     

    And I'm not letting you take away my god-given right to ignore return values! Big Smile

  • User profile image
    wkempf

    Maddus Mattus said:
    Massif said:
    *snip*

    I hate var's

     

    they are for lazy programmers Smiley

     

    and worker.DoWork() would not be possible, because DoWork has a return type. Ignoring the return is not 'first class' as Erik would call it Smiley

    Today, worker.DoWork() is valid. You don't have to care that there's a return type. In a theoretical world, you can't make it always required that you capture the return value as that would be a breaking change. You could make it required only when there's such "overloads", but that's probably not a good idea as it introduces some tricky versioning scenarios. And that's all ignoring the very valid points that Massif has made. You may not like 'var', but it exists. There's also the issue with base types causing ambiguity. Technically, none of this prevents the introduction of overloading based on return type, as it's really no different from overloading based on out parameters, but it certainly seems like it would be much more confusing for developers and maintainers. I don't think it's a good idea.

  • User profile image
    Maddus Mattus

    Massif said:
    Maddus Mattus said:
    *snip*

    Or of course:

     

    ojbect thing = worker.DoWork();

     

    And, if you have a class A which inherits from B which inherits from C (and DoWork implementations returning As and Bs) what does:

     

    C wtf = worker.DoWork();

     

    Resolve as? It'd just be too confusing for us humble programmers.

     

    And I'm not letting you take away my god-given right to ignore return values! Big Smile

    I'm going to talk to god (Erik) about that!

     

    Object should become a forbidden word, you can only inherit from object.

     

    let's say we have A that inherits from B

     

    if we have two methods:

     

    A DoWork() and B DoWork()

     

    A a = worker.DoWork() would result in using A DoWork(), if you want to use the B one use B b = worker.DoWork(), you lazy git Wink

     

    I've programmed for 6+ years now and I've never run into these problems before. Until recently,... But anyway,.. I've just attached a bool to the end of the parameters B DoWork(bool thisisherebecauseprogramlanguagesarestupid);

  • User profile image
    Minh

    Maddus Mattus said:
    Massif said:
    *snip*

    I'm going to talk to god (Erik) about that!

     

    Object should become a forbidden word, you can only inherit from object.

     

    let's say we have A that inherits from B

     

    if we have two methods:

     

    A DoWork() and B DoWork()

     

    A a = worker.DoWork() would result in using A DoWork(), if you want to use the B one use B b = worker.DoWork(), you lazy git Wink

     

    I've programmed for 6+ years now and I've never run into these problems before. Until recently,... But anyway,.. I've just attached a bool to the end of the parameters B DoWork(bool thisisherebecauseprogramlanguagesarestupid);

    Maddus

     

    But there's a legit reason to do BaseClass b = DoWork();

     

    It's not that what you propose isn't technically possible by the compiler, it just breaks OOP. You don't want the compiler to break OOP do you?

  • User profile image
    rhm

    Overloads aren't discriminated on return types in any language I know of. There are good reasons for it.

     

    It would mean you'd need to have a "target type" for an expression in order to resolve which overload to use. That's OK in a trivial example such as yours where you can take it from the LHS of the assignment, but what about when you are evaluating a subexpression with overloads based on return type and that subexpression is passed as a parameter to function for which there are multiple overloads - which do you chose then?

  • User profile image
    Maddus Mattus

    Minh said:
    Maddus Mattus said:
    *snip*

    Maddus

     

    But there's a legit reason to do BaseClass b = DoWork();

     

    It's not that what you propose isn't technically possible by the compiler, it just breaks OOP. You don't want the compiler to break OOP do you?

    To make an omelet, you have to break some eggs

     

    You could do something like

    default A doWork()

    B doWork()

    C doWork()

    D doWork()

     

    would be cool!

     

    Go do some work Smiley

  • User profile image
    Minh

    Maddus Mattus said:
    Minh said:
    *snip*

    To make an omelet, you have to break some eggs

     

    You could do something like

    default A doWork()

    B doWork()

    C doWork()

    D doWork()

     

    would be cool!

     

    Go do some work Smiley

    What if I had this really common scenario?

     

    class Chicken { }

    class Hen : Chicken { }

    class Rooster : Chicken { }

     

    List<Chicken> roster = new List<Chicken>();

     

    roster.Add(DoWork());

     

  • User profile image
    Massif

    Minh said:
    Maddus Mattus said:
    *snip*

    What if I had this really common scenario?

     

    class Chicken { }

    class Hen : Chicken { }

    class Rooster : Chicken { }

     

    List<Chicken> roster = new List<Chicken>();

     

    roster.Add(DoWork());

     

    That was going to be my next question Smiley

     

    And for all that breakage and confusion, what does it get you really?

  • User profile image
    W3bbo

    Overloading on formal parameters is to say "do the same thing, but with this input". You differentiate methods by names according to what they do, if they do the same thing then they should return the same type of object.

     

    That's why I don't think this should be implemented.

  • User profile image
    Deactivated User

    Comment removed at user's request.

  • User profile image
    vesuvius

    vault said:
    Maddus Mattus said:
    *snip*

    I used to think so too, but after programming in Visual Basic properly, less is more.

     

    In C# you have

     

    MyClass myClass = new MyClass

     

    Whereas in VB you have

     

    Dim MyClass = As New MyClass

     

    which is elegant, notwithstanding the 'Dim' keyword of course - what a tragedy

     

    var myClass = new MyClass

     

    results in far less code, and is infinitely more readable in the long run, especially with long namespaces and properly formatted Linq queries. 

    Oops, wrongemail address

     

    I used to think so too, but after programming in Visual Basic properly, less is more.

     

    In C# you have 


    MyClass myClass = new MyClass

     

    Whereas in VB you have 


    Dim MyClass = As New MyClass

     

    which is elegant, notwithstanding the 'Dim' keyword of course - what a tragedy 


    var myClass = new MyClass

     

    results in far less code, and is infinitely more readable in the long run, especially with long namespaces and properly formatted Linq queries.

  • User profile image
    W3bbo

    vault said:
    Maddus Mattus said:
    *snip*

    I used to think so too, but after programming in Visual Basic properly, less is more.

     

    In C# you have

     

    MyClass myClass = new MyClass

     

    Whereas in VB you have

     

    Dim MyClass = As New MyClass

     

    which is elegant, notwithstanding the 'Dim' keyword of course - what a tragedy

     

    var myClass = new MyClass

     

    results in far less code, and is infinitely more readable in the long run, especially with long namespaces and properly formatted Linq queries. 

    That VB code fragment introduces an ambiguarity, variable "MyClass" with type "MyClass"; but I get your point.

     

    I recognise that in cases where the implementation matters as much as the interface the "traditional way" of doing things could make way for some kind of succint syntax for instantiation, how about this:

     

    SomeClass foo = new; // default constructor

    SomeClass foo = new( /* constructor params go here */ );

  • User profile image
    Maddus Mattus

    Massif said:
    Minh said:
    *snip*

    That was going to be my next question Smiley

     

    And for all that breakage and confusion, what does it get you really?

    That I can do this:

     

    FinanceResult<FinanceItem> GetActuals();

    FinanceResult<FinanceItem, Dimension1, Dimension2> GetActuals();

     

    But I guess I should do:

     

    FinanceResult<FinanceItem> GetActuals();

    FinanceResult<FinanceItem, Dimension1, Dimension2> GetActuals<Dimension1, Dimension2>();

     

    Boring Smiley

  • User profile image
    Ion Todirel

    Maddus Mattus said:
    Massif said:
    *snip*

    That I can do this:

     

    FinanceResult<FinanceItem> GetActuals();

    FinanceResult<FinanceItem, Dimension1, Dimension2> GetActuals();

     

    But I guess I should do:

     

    FinanceResult<FinanceItem> GetActuals();

    FinanceResult<FinanceItem, Dimension1, Dimension2> GetActuals<Dimension1, Dimension2>();

     

    Boring Smiley

    Gosh, the right way to do it:

     

    public interface FinanceService // Just for grouping

    {

        FinanceResult<FinanceItem> GetActuals();

        FinanceResult<FinanceItem, Dimension1, Dimension2> GetActualsWithDimension();

    }

  • User profile image
    Maddus Mattus

    Ion Todirel said:
    Maddus Mattus said:
    *snip*

    Gosh, the right way to do it:

     

    public interface FinanceService // Just for grouping

    {

        FinanceResult<FinanceItem> GetActuals();

        FinanceResult<FinanceItem, Dimension1, Dimension2> GetActualsWithDimension();

    }

    w00t thanks Smiley

Comments closed

Comments have been closed since this content was published more than 30 days ago, but if you'd like to continue the conversation, please create a new thread in our Forums, or Contact Us and let us know.