Something I'd like to see in C#

Jun 15, 2015 10:14

It's quite common to end up writing methods that take booleans to say whether certain functionality should be switched on or off. It would be nicer to use enumerations, not least because that way you couldn't end up getting them the wrong way around.

Something like:
void DoSomething(Thing thing, bool withLogging, bool withRollBack){}which would ( Read more... )

Leave a comment

cartesiandaemon June 15 2015, 09:28:28 UTC
It seems like a lot of the time the parameter is a bool, in which case named parameters seem to do this?

DoSomething(thing, logging:True, rollback:False)

That's one of the things in C# which I wish C++ would hurry up and have properly.

Of course, anywhere where you do want more than two options, your enum syntax would be useful. Especially if, for the rare cases where you need it, you could use that as a variable type. And if there was a syntax that prevented the enum polluting any namespaces outside the function.

Reply

steer June 15 2015, 10:06:28 UTC
Yes -- I was going to say named parameters too. It seems clear -- arguably more so than enumeration. (And having just designed something in a language with named parameters and had to move it to one without you realise how damn clear and useful they are.)

Reply

cartesiandaemon June 15 2015, 10:22:46 UTC
Yeah. It's something where the lack annoys me, because it seems like you could add it with no runtime overhead, and nothing in the way of ambiguous or non-backwards-compatible syntax (if you choose the syntax well), so I can't see any obvious reason NOT to have it, and to me it looks a lot clearer (and hence more reliable).

Reply

steer June 15 2015, 10:45:16 UTC
Nod. Last project I was working on the other coder went through a lot of hoops to ensure that two int parms distinguished only by position could not be used in the wrong order. In fact after he did that it took me ages to remember how to actually call the damn thing.

Named parameters are a big plus for me but I guess some people see it as incompatible with the style of their language. In C++ in fact I think there's no requirement that the names in a prototype and an implementation be the same so

class MyObject {
void wibble(int thisInt, int thatInt).
}

can by implemented as
MyObject::wibble(int thatInt, int thisInt);

And I imagine requiring parameter names be consistent in prototype and impl would break code? So I imagine there's scope for a lot of confusion.

Reply

cartesiandaemon June 15 2015, 10:53:39 UTC
in C++ in fact I think there's no requirement that the names in a prototype and an implementation be the same so

Oh yes, I'd forgotten that. I'm not sure it's a good thing, but it's how it's always been.

But IIRC whenever you call a function, you're calling a particular prototype which is then linked to the implementation at link time. For instance, I think the default parameters are specified in the prototype not implementation and could in principle be different in two different prototypes although that would be horrible. So I assumed this would work the same way -- the compiler would match the parameter names where you call it to the prototype, turn it back into a call to a function name based on positional parameters, and then the linker would link that with the implementation ignoring the names of the parameters?

Reply

steer June 15 2015, 11:08:47 UTC
Hahaha... oh my god, you're right: so we could have:

class MyObject{
void myMethod( int myThis=1, int myThat=2);
}

MyObject::MyMethod (int myThat=3, int myThis=4)
{
// Hooray for ambiguity
}

C++ really does allow you to confuse yourself in multiple ways. Actually I don't think the named parameters make things terribly worse here.

The bad thing is that, in fact, sometimes prototype argument names do get out of step with the implementation due to careless refactoring.

Reply

cartesiandaemon June 15 2015, 11:19:25 UTC
:)

I don't think it's _quite_ that bad. I think the compiler gives an error or at least a warning (?) if you specify contradictory defaults in the declaration and implementation, or two different declarations seen by the same file. I agree it's not very reliable, but I think to actually screw it up you need two different header files and only ever include one of them, or to have a contradictory header file and implementation file, and not include the header in the implementation...

Reply

steer June 15 2015, 11:22:56 UTC
You're right -- it complains if you specify defaults in the impl. This is valid though

class MyObj {
void myMethod(int thisVar=1, int thatVar=2);
};

void MyObj::myMethod(int thatVar, int thisVar)
{

}

Reply

cartesiandaemon June 15 2015, 11:47:07 UTC
Oh yes. That's always possible with C++ and it really shouldn't be.

Reply

ggreig June 15 2015, 11:31:05 UTC
Named parameters are a reasonable second best, but it's hard to encourage/enforce their use. People too lazy to create an enum are also generally speaking too lazy to use a named parameter to make themselves clear.

Inline enum definitions would suffer from the same problem, but perhaps - hopefully! - to a lesser extent. Personally I'd still rather have the enum properly and separately defined and documented (with XML comments), but I'm at the picky end of the scale on stuff like that.

Even when there are only two options, an enum's generally better than a Boolean because if an unforeseen third option comes up, adding it is not necessarily a breaking change.

Reply

skington June 15 2015, 16:39:09 UTC
Perl developer here, so take that with a pinch of salt as cultures will be different.

If I had a method like this with three (or more) parameters which weren't in a perfectly obvious order, I'd say "this method call is too complex for positional parameters, it wants named arguments". And if that didn't happen, it would fail code review. That's how you enforce that sort of thing.

This also lets you provide useful defaults, so if e.g. you expected to log things, but didn't normally need a rollback, you'd just say doSomething(thing => thingObject) and that would be that.

Reply

andrewducker June 16 2015, 04:48:34 UTC
Named parameters allow you to do it - but they don't force people to do so, so people not following the style guide would still just be saying "DoStuff(myStuff,true,false);"

But yes, definitely allows it.

Reply


Leave a comment

Up