5

It annoys me that I am required to have them, for an example consider the case

public class IsEquipmentAvailable : Specification<Equipment>
{
    public IsEquipmentAvailable() : base(equipment => equipment.CartEquipments
        .All(o => o.RentState == RentState.Done))
}

However, I am not allowed to write this as I need to add {}, in c# that is at least 2 extra lines of the boilerplate code that do nothing. If I want to support directed expression graph chain calls or just instantiating element from an expression, it becomes even worse.

public class IsEquipmentAvailable : Specification<Equipment>
{
    public IsEquipmentAvailable(Expression<Func<Equipment, bool>> expression) 
        : base(expression)
    {
    }

    public IsEquipmentAvailable(ISpecification<Equipment> specification) 
        : base(specification)
    {
    }

    public IsEquipmentAvailable() : base(equipment => equipment.CartEquipments
        .All(o => o.RentState == RentState.Done))
    {
    }
}

The functional programming side of me laughs from ignorance because he does not know better. Sometimes there are valid reasons why things are the way they are, so I would like to know reasoning behind this.

Margus
  • 19,694
  • 14
  • 55
  • 103
  • 6
    "in c# that is at least 2 extra lines" — you can place `{}` on the same line you have your `base(...)`. As to the question: many things might be removed in certain contexts but a) it requires some efforts with little gain and b) it creates inconsistency and the more inconsistency program code might have the harder it is to write it. – ixSci May 19 '16 at 05:47
  • @ixSci I am aware of this, you could do http://stackoverflow.com/questions/32900895/allow-same-line-empty-methods-in-resharper however it does not change the question. Often teams have rules and you can not decide from others and if they use auto format, then you get git changes you do not want. So it does not solve the problem. – Margus May 19 '16 at 05:50
  • Guess ixSci's main point is: the feature of allowing to ommit the `{}` is not there because nobody implemented it. And nobody implemented it yet because it was probably never proposed or the c# developers said: what's the _net_ benefit. Ok, it would allow to ommit them, but what draw backs are there: is the syntax still unambigous? what does it cost to implement/test/document this feature? and does the benefit justify all this. – René Vogt May 19 '16 at 05:57
  • As a sidenote, extern constructors can be specified without a body: https://msdn.microsoft.com/en-us/library/aa645602(v=vs.71).aspx so it does seem like it's been implemented to some degree. – Evan Trimboli May 19 '16 at 06:01
  • Why is a lambda expression built with =>? Why is there no &&= operator? Why do we use curly braces? ... A programming language is something artificial which is as it had been created. You can spend hours discussing why things hadn't been created differently. – Stefan Steinegger May 19 '16 at 14:07
  • @StefanSteinegger About "=>" I did knew, but now have forgotten. It was like ":=" or ":>" have different meanings "=>" can be read as "such that", when read out loud made sense. Use of curly braces comes from BCPL, where $( and $) were used, but later evolved to { }. While "&=" is actually beneficial as 1 registry move is done less (in place operation) than in "= ... & ...", it is not the case for &&=. Several language designers have noted that they try to keep things minimal, it does not make sense to support &&= if it does not bring same value. It is ok, not to know. I just want to know. – Margus May 19 '16 at 14:28
  • @Margus: There are reasons for everything, as there are reasons to make it different. I just listed some examples of language things that came to my mind. You can take any syntax rule of the language and ask why it had been designed like this and not otherwise. – Stefan Steinegger May 20 '16 at 09:22

1 Answers1

2

The language does allow for an omission - just the opposite one to the one you we're looking for (10.11.1):

All instance constructors (except those for class object) implicitly include an invocation of another instance constructor immediately before the constructor-body

and:

If an instance constructor has no constructor initializer, a constructor initializer of the form base() is implicitly provided. Thus, an instance constructor declaration of the form

C(...) {...}

is exactly equivalent to

C(...): base() {...}

So, there's no exception for constructors that have initializers because, per the language spec, all constructors do in fact have initializers.


Also, the language is quite consistent here, when you think about it - the only places where you're allowed to completely omit the body of a method are where you are, specifically, prohibited from supplying a body - such as extern constructors, as mentioned in the comments, or abstract methods. Everywhere else, you must supply a body, even if you choose to make it empty.

Community
  • 1
  • 1
Damien_The_Unbeliever
  • 234,701
  • 27
  • 340
  • 448