crazy idea?? named parameters in constructor

  • Thread starter Thread starter Daniel Billingsley
  • Start date Start date
D

Daniel Billingsley

I think it's really nice to be able to do code like

someVariable = someMethod(new SomeClass("some text"));

However, as method signatures are number and types of parameters, you're
limited to having one constructor that accepts a single string, for example.

Call me crazy, but wouldn't it be useful to be able to have a syntax where
you could set properties in a statement like the one above, without being
limited to just what you could incorporate into a ctor signature?

public class SomeClass
{
private string _var1;
private string _var2;
private string _var3;

// public properties Var1, Var2, and Var3 here

public SomeClass()
{
}
}

and then be able to say

someVariable = someMethod(new SomeClass(!Var2 = "some text",
!Var3="something else"));

The "!" being of course some convention I just made up. The point being
that it still allows the rather concise line above compared to the
following:
SomeClass cls = new SomeClass();
cls.Var2 = "some text";
cls.Var3 = "something else";
someVariable = someMethod(cls);

But it gives total flexibility on what's set before it is used in
someMethod(). (Think of the way "using" looks cleaner than the try..finally
(and test for null) blocks.
 
sorry but can't say that I agree. your proposal looks very messy. I personally prefer multiple lines for clarity. the last thing we need is to squeeze more and more code into one line

----- Daniel Billingsley wrote: ----

I think it's really nice to be able to do code lik

someVariable = someMethod(new SomeClass("some text"))

However, as method signatures are number and types of parameters, you'r
limited to having one constructor that accepts a single string, for example

Call me crazy, but wouldn't it be useful to be able to have a syntax wher
you could set properties in a statement like the one above, without bein
limited to just what you could incorporate into a ctor signature

public class SomeClas

private string _var1
private string _var2
private string _var3

// public properties Var1, Var2, and Var3 her

public SomeClass(




and then be able to sa

someVariable = someMethod(new SomeClass(!Var2 = "some text"
!Var3="something else"))

The "!" being of course some convention I just made up. The point bein
that it still allows the rather concise line above compared to th
following
SomeClass cls = new SomeClass()
cls.Var2 = "some text"
cls.Var3 = "something else"
someVariable = someMethod(cls)

But it gives total flexibility on what's set before it is used i
someMethod(). (Think of the way "using" looks cleaner than the try..finall
(and test for null) blocks
 
I am confused. Why not just do this:
public class SomeClass
{
private s1 = null;
private s2 = null;
private s3 = null;
public SomeClass()
{
}
public SomeClass(string s1, string s2, string s3)
{
this.s1 = s1;
this.s2 = s2;
this.s3 = s3
}
}

Test for nulls and values as is right for your class, etc.
 
But it gives total flexibility on what's set before it is used in
someMethod(). (Think of the way "using" looks cleaner than the try..finally
(and test for null) blocks.

There are languages where this syntax is supported, but in C# you can always
provide multiple overloads on the constructor. This doesn't achieve what
you're asking exactly but is an alternative that is widely used.

The syntax is also supported by attributes in C#, as long as you provide
public properties with get\set accessors you can do the following:

[MyAttribute( Var2="some text", Var3="something else" )]

But again, isn't exactly what you're suggesting (being specific to
attributes). I don't think you'll see this in all classes, as multiple
constructor overloads do the same thing (in a more constrained fashion).

n!
 
I second this suggestion from William . This does exactly what you want
without having to mangle the language with new features like '!'

JIM
 
I'm missing something here. If SomeClass has 20 properties and it has 3
different constructors that at most set 3 properties, then isn't he
suggesting a method that you could set all 20 if you wanted, or more
particularly, a specific 3 or them that aren't the ones included in the
constructor? If that's what his point is, then it seems like a decent
enough idea although it woudl be nightmarish to program and seems to be
essentially what VB.NET's optional parameters do but a cleaner version.
However everyone seems to disagree so there's a good probabilty I'm missing
what his goal was .

Thanks,

Bill

--

W.G. Ryan, eMVP

http://forums.devbuzz.com/
http://www.knowdotnet.com/williamryan.html
http://www.msmvps.com/WilliamRyan/
http://www.devbuzz.com/content/zinc_personal_media_center_pg1.asp
 
There are languages where this syntax is supported, but in C# you can
always
provide multiple overloads on the constructor. This doesn't achieve what
you're asking exactly but is an alternative that is widely used.

No, that won't work because I'd need multiple overloads with the same
signature.
 
Yeah Bill, I was talking about not having to write 40 constructors for
various combinations of things you wanted to set.

William's suggestion was very helpful, but still requires I have a very
large constructor in Bill's example - 17 parameters of which won't be used
in any given instantiation. That would work, but it isn't very easy to work
with.

It doesn't seem like much of a nightmare to program to me... intellisense
could just watch for the special character (like it watches for "(" and so
on now) and then give you a list of the public properties. The compiler
just has to convert to the appropriate IL as if you had written
SomeClass var1 = new SomeClass();
var1.Property1 = "something;
var1.Property4 = "something else";
 
There are languages where this syntax is supported, but in C# you can
always

No, that won't work because I'd need multiple overloads with the same
signature.

I wasn't suggesting multiple overloads with each parameter in a different
location. I meant:

public MyObject( int itemA )
{
}

public MyObject( int itemA, int itemB )
{
}


etc.

As I said, this isn't exactly what you're after (as I said, more constrained
as the parameters come in a predefined order). But is supported by C# and is
a widely used idiom (and thus familiar).

n!
 
If you have a class that requires that much initializing then you have most
likely desinged something wrong. Classes are supposed to be fairly self
contained units. If they require that much outside control then maybe they
should not exist as a class at all, or your class should have other helper
classes.

JIM
 
Actually, what is wrong with

new SomeClass ( val1, val2, null, null, val5, null, val7, val8, null, null
...... )

Simply fill in the ones you want and make the others null.

JIM
 
May I suggest two round-trips:

1 - just pass something like a hashtable to your constructor
2 - use varaible-length parameters:
public Class1(params object[] args)
{
string result = "";
for (int i=0; i < args.Length-1; i+=2)
{
string key = args.ToString();
string val = args[i+1].ToString();

result += key + " = " + val + "\n";
}
}

if constructing this class with
Class1 c = new Class1("K1", "V1", "K2", "V2");
result contains:
K1 = V1
K2 = V2

Olivier DALET
-----------------
 
Actually what you are suggesting is not very hard.

You can easyly make this behaviour yourself. Split your string up in parts,
use Reflection to set your properties and basicly, thats it.

BUT

By providing such a constructor you totally have no control what the enduser
(this may be another developer) is actually doing with your class.

public class Daniel_Billingsleys_BancAccount
{
public Daniel_Billingsleys_BancAccount(double aBalance){
if (aBalance < 0) throw ...
}

public Daniel_Billingsleys_BancAccount(string Init)
{
DoWhatever here?
};

}

Account = new Daniel_Billingsleys_BancAccount("Balance = -100000$");

Trust me, designing a class is already hard enough, you really don't want
other developers to override all encapsulation.

Kind regards

Alexander
 
Call me crazy,

Yes, I will. You ARE crazy.

but wouldn't it be useful to be able to have a syntax where
you could set properties in a statement like the one above, without being
limited to just what you could incorporate into a ctor signature?

No, it wouldn't. It would be hatred.
public class SomeClass
{
private string _var1;
private string _var2;
private string _var3;

// public properties Var1, Var2, and Var3 here

public SomeClass()
{
}
}

and then be able to say

someVariable = someMethod(new SomeClass(!Var2 = "some text",
!Var3="something else"));

That is the most nonsensical thing I have ever seen, as those variables
are declared as private to the class, and this (certainly amongst
programmers
with dumb design skills) would give rise to stupid hacks to set the values
of
private variables. Doh!
Setting the variables is the class's responsibility, they might not just be
simple
assignments, for example. Think yourself lucky you get to supply parameters
to the constructor, you don't in VB6.
The "!" being of course some convention I just made up. The point being
that it still allows the rather concise line above compared to the
following:
SomeClass cls = new SomeClass();
cls.Var2 = "some text";
cls.Var3 = "something else";
someVariable = someMethod(cls);

But it gives total flexibility on what's set before it is used in
someMethod(). (Think of the way "using" looks cleaner than the try..finally
(and test for null) blocks.

It would just give rise to stupid, dirty, code.
 
B0nj said:
That is the most nonsensical thing I have ever seen, as those variables
are declared as private to the class, and this (certainly amongst
programmers with dumb design skills) would give rise to stupid hacks to set
the values of private variables. Doh!

I don't think you read closely enough. Var2 and Var3 *aren't* private
variables. They're public properties, as specified in the comment.

I dislike it in terms of making the language more complicated than it
needs to be for little gain, but it's not nearly as unsound as you're
making it out to be.
 
Uh... that doesn't make a lot of sense. It doesn't create any more "outside
control" than having public properties in the first place. The IDE and
compiler could/would enforce the proper use in the same way as with
properties.
 
How does the factory pattern help? I'd just end up with 40 "Get..." instead
of 40 constructors or one "Get" method with 20 parameters instead of a
constructor with 20. Could you elaborate on what you were thinking?

Aside from exploring that, I appreciate everyone's comments. Of course the
20 parameter example was an exaggeration to make the point. Since in
reality I'm probably talking about only a handful, I think the solution
several have proposed will work just fine.

object1 = new Class1("something", null, null);
object2 = new Class1(null, "something", "blah blah");
 
I think it's really nice to be able to do code like

someVariable = someMethod(new SomeClass("some text"));
Car c = Car.CreateCar(typeof(Convertible), typeof(V8));
or
Car c = Car.CreateCar(typeof(Hardtop), typeof(Inline6));
However, as method signatures are number and types of parameters, you're
limited to having one constructor that accepts a single string, for example.
public class Car
{
public Car()
{
About = "Car base class";
}
public static Car CreateCar(System.Type carType, System.Type
engineType)
{
Car car = (Car)Activator.CreateInstance(carType);
car.engine = (Engine)Activator.CreateInstance(engineType);
return car;
}
public string About;
public int Cylinders
{
get
{
return engine.Cylinders;
}
}
protected Engine engine;
}

public class Convertible : Car
{
public Convertible() : base()
{
About = "Drophead coupe";
}
}

public class Hardtop : Car
{
public Hardtop() : base()
{
About = "Fixedhead coupe";
}
}
Call me crazy, but wouldn't it be useful to be able to have a syntax where
you could set properties in a statement like the one above, without being
limited to just what you could incorporate into a ctor signature?

There is nothing wrong with the concept. The throw-away code above
provides a simple example how this can be done. If there are four
Car-derived classes and three Engine-derived classes the single
CreateCar method can be used to create all twelve combinations of Car
and Engine types.

regards
A.G.
 
Thanks for the input, but that's a rather different matter. The (extremely
exaggerated) example case is where there are 20 parameters but they're *all
strings* and only 3 or 4 will be set for any given instance of the class.

As has been pointed out, this may indicate a poor design, and in any event
there is a solution for the more realistic case of a half dozen or so
parameters of which 2 or 3 will be set.
 
Back
Top