one line struct initialization

  • Thread starter Thread starter Zytan
  • Start date Start date
Is it possible, as in C? I don't think it is. Just checking.

If you provide a constructor that will initialize all members.


Mattias
 
Is it possible, as in C? I don't think it is. Just checking.
Why wouldn't it be possible? What exactly are you referring to?

I mean like so:

int x = 4; // declared and initialized in one line

struct abc { ... };
abc = ...; // declared and initialized in one line. Is this possible?

Zytan
 
Is it possible, as in C? I don't think it is. Just checking.
If you provide a constructor that will initialize all members.

I wasn't looking to use a constructor. But, maybe I need one.
Does "int x = 4;" invoke a constructor for 'int'? Is that how
declarations and initializations are done on the same line?

Zytan
 
struct abc { ... };
abc = ...; // declared and initialized in one line. Is this possible?

Oops, I mean:

struct abc { ... };
abc y = ...; // declared and initialized in one line. Is this
possible?

Zytan
 
I wasn't looking to use a constructor. But, maybe I need one.

Well maybe you can get by with an implicit conversion operator
instead. It depends on what kind of expression you want on the right
hand side of the assignment.

One way or another the RHS expression must be turned into an instance
of your struct.

Does "int x = 4;" invoke a constructor for 'int'?

No, but int in special since you can write literals for it in C# and
there are special IL opcodes for it.


Mattias
 
Zytan said:
I wasn't looking to use a constructor. But, maybe I need one.
Does "int x = 4;" invoke a constructor for 'int'? Is that how
declarations and initializations are done on the same line?

Well, the primitive types are a special case - but yes, if you want to
initialize a struct, you generally need to call a constructor. If it's
a mutable struct (generally a bad idea) you *could* just do:

MyStruct x;
x.SomeProperty = ...;

but it's generally better to have a constructor which fully constructs
the struct, and call that.
 
Well maybe you can get by with an implicit conversion operator
instead. It depends on what kind of expression you want on the right
hand side of the assignment.

One way or another the RHS expression must be turned into an instance
of your struct.

Yes, it sounds like using a constructor is the proper way, then.
No, but int in special since you can write literals for it in C# and
there are special IL opcodes for it.

Right, that's what I thought.

Zytan
 
Well, the primitive types are a special case - but yes, if you want to
initialize a struct, you generally need to call a constructor.

I guess I was just looking for something as simple as what you can do
with initializing an array:

int[] x = new int[] { 4, 5, 6, 7 };
If it's
a mutable struct (generally a bad idea) you *could* just do:

MyStruct x;
x.SomeProperty = ...;

but it's generally better to have a constructor which fully constructs
the struct, and call that.

Yes, I think I need a constructor. I did notice that C# complains if
you only initialize a portion of the fields in the struct (if you miss
one) and then attempt to use it. So, it is safe (perhaps not so in
earlier versions?). But, a c'tor seems more safe.

A mutable struct is a bad idea? What is a mutable struct? I know
mutable means it can change. But, unless all fields are private,
isn't the struct mutable? Or is this precisely what you mean, that
struct fields should all be private (almost like a class)?

Zytan
 
What goes in the dots.

struct abc { int x; double y; AnotherStruct s; };
abc y = { 100, 3.14, ??? };

It works up until the ???, since it's a struct. I don't know what to
put there.

Zytan
 
Zytan said:
Well, the primitive types are a special case - but yes, if you want to
initialize a struct, you generally need to call a constructor.

I guess I was just looking for something as simple as what you can do
with initializing an array:

int[] x = new int[] { 4, 5, 6, 7 };

Well, you can do:

MyStruct[] x = new MyStruct[] { new MyStruct(1), new MyStruct(2) };

etc
Yes, I think I need a constructor. I did notice that C# complains if
you only initialize a portion of the fields in the struct (if you miss
one) and then attempt to use it. So, it is safe (perhaps not so in
earlier versions?). But, a c'tor seems more safe.

Yes, that's much better.
A mutable struct is a bad idea? What is a mutable struct? I know
mutable means it can change. But, unless all fields are private,
isn't the struct mutable? Or is this precisely what you mean, that
struct fields should all be private (almost like a class)?

All fields *should* be private, for both structs and classes. If you
need to access them from outside, use methods or properties. A mutable
struct would be one which let you change the values, whether via
properties or methods (or, of course, non-private fields).
 
Zytan said:
struct abc { int x; double y; AnotherStruct s; };
abc y = { 100, 3.14, ??? };

It works up until the ???, since it's a struct. I don't know what to
put there.

You don't do it like that - you have a constructor, and do:

abc y = new abc (100, 3.14, new AnotherStruct(...));
 
I guess I was just looking for something as simple as what you can do
with initializing an array:
int[] x = new int[] { 4, 5, 6, 7 };

Well, you can do:

MyStruct[] x = new MyStruct[] { new MyStruct(1), new MyStruct(2) };

Yes, sorry, I didn't mean that I wanted an array of struct, I mean
that I wanted to do something like this:

MySrtuct x = new MyStruct { field1, field2, field3, field4 };

Where fieldX are the fields in MyStruct, which could, themselves, be
structs.
All fields *should* be private, for both structs and classes.

Even for structs? But sometimes a struct is just something simple,
like holding x and y for the concept of a point.
If you
need to access them from outside, use methods or properties.

Ok, I will try adding a constructor, and making everyting private. I
think in my case this will do just fine.
A mutable
struct would be one which let you change the values, whether via
properties or methods (or, of course, non-private fields).

Ok.

Zytan
 
struct abc { int x; double y; AnotherStruct s; };
You don't do it like that - you have a constructor, and do:

abc y = new abc (100, 3.14, new AnotherStruct(...));

Ok. Thanks, Jon.

Zytan
 
I guess I was just looking for something as simple as what you can do
with initializing an array:
int[] x = new int[] { 4, 5, 6, 7 };
Well, you can do:
MyStruct[] x = new MyStruct[] { new MyStruct(1), new MyStruct(2) };

Yes, sorry, I didn't mean that I wanted an array of struct, I mean
that I wanted to do something like this:

MySrtuct x = new MyStruct { field1, field2, field3, field4 };

Where fieldX are the fields in MyStruct, which could, themselves, be
structs.
All fields *should* be private, for both structs and classes.

Even for structs? But sometimes a struct is just something simple,
like holding x and y for the concept of a point.

Yes, but be careful here: note the difference between making a point a
class versus making it a struct.

If you make a Point class, then you hold references to instances, and
usually (unless you Clone) you can have many references pointing to
the same instance. Change the instance and the data accessible through
all of the relevant references changes. (That is, conceptually, if you
change the coordinates of the point instance then many parts of your
program may see that change.) As well, a Point class instance is
"defined" by more than just its coordinates: you can have only one
instance of (5, 4), or two instance, or a dozen, and it makes sense to
talk about "this instance of (5, 4) versus that one."

If you make a Point struct, then you simply hold the value (5, 4).
Whenever you pass it or assign it to another Point, you create a copy.
It is a value, like an integer, and so changing one value does not
affect any other value with the same coordinates. A Point struct is
defined only by its coordinates and nothing else: one (5, 4) is
equivalent to any other (5, 4). It makes no sense to talk about "this
(5, 4) versus that one."

I don't know how good an explanation that was, but the point (if
you'll pardon the pun) is that the semantics change significantly.

The reason that you usually want immutable structs (that is, structs
with constructors that initialize all members, no public fields, and
no properties with setters or methods that change the struct's value)
is that struct is usually intended to create new value types, like
double, int, float, DateTime, etc. Most ex-C programmers (like me) try
at least once to use "struct" to build a "light" class of just fields
and no methods. I tried to use it for StockItem or some such thing. It
was a disastrously bad idea. I learned my lesson.

I now have a Fraction struct that allows me to perform math on
fractions. The struct has properties and methods, but note that any
property or method that would usually alter the struct instead returns
a new one. For example:

public Fraction Normalize()
{
Fraction result = ... ;
return result;
}

So instead of normalizing a Fraction by saying fract.Normalize(), I
have to say:

Fraction norm = fract.Normalize();

Again, it's a value, not a class instance. Values generally don't
morph themselves into other values: variables are rather assigned new
values. (If you want a parallel with native types, you aren't allowed
to mess with the individual bits in an integer, but you are allowed to
do an operation that masks out bits in an integer and then assign the
result back to the same variable that held the original integer.)
 
Zytan said:
MyStruct[] x = new MyStruct[] { new MyStruct(1), new MyStruct(2) };

Yes, sorry, I didn't mean that I wanted an array of struct, I mean
that I wanted to do something like this:

MySrtuct x = new MyStruct { field1, field2, field3, field4 };

Where fieldX are the fields in MyStruct, which could, themselves, be
structs.

Well, change the braces to brackets and define the appropriate
constructor, and you're there.
Even for structs? But sometimes a struct is just something simple,
like holding x and y for the concept of a point.

That doesn't mean it's not worth encapsulating them in properties.
Non-private fields are highly discouraged. You get much more control
and power with properties. You can add in validation etc later, or even
potentially change the underlying type/implementation without callers
caring.
Ok, I will try adding a constructor, and making everyting private. I
think in my case this will do just fine.

Goodo.
 
Bruce, wow, that was an amazing explanation! Thanks!
Even for structs? But sometimes a struct is just something simple,
like holding x and y for the concept of a point.

Yes, but be careful here: note the difference between making a point a
class versus making it a struct.
[snip]

Yes, I already knew the fine differences between references and value
types. I think of references as pointers to data, and by making more
pointers to the same data, if you change the data, all of the usage of
any of those pointers to it will see the changed data. Your
explanation was perfect, however.
The reason that you usually want immutable structs (that is, structs
with constructors that initialize all members, no public fields, and
no properties with setters or methods that change the struct's value)
is that struct is usually intended to create new value types, like
double, int, float, DateTime, etc.

Ah, so now I get it. This is the key. If you use struct as a new
value type, then, yes, the data within it should never change. It is
set on construction. And if it should change, it would be as the
result of an overloaded assignment operator. I totally get it now.
Thanks.
Most ex-C programmers (like me) try
at least once to use "struct" to build a "light" class of just fields
and no methods. I tried to use it for StockItem or some such thing. It
was a disastrously bad idea. I learned my lesson.

Well, right now, I want to use a struct to basically store a bunch of
data (strings, ints, etc.) that are all related. I really have no use
to doing anything 'on' them, such as add them together, or whatever,
or even change them. I just want to store the information into one
variable, and later look at it. So, I could make the fields all
private, and then make readonly properties for each, but it's so much
easier to just make them public (but, yes, that means you could change
them, so it's quicker code, but not as robust).

I totally agree with you for such cases as when you want to make a new
value type -- now I get why to use a struct with methods. That's
basically what all the elementary values types are (well, in concept,
anwyay).

Bruce, thanks for this amazing explanation. It's so basic and
elementary, but it is so powerful at the same time.

Zytan
 
Yes, sorry, I didn't mean that I wanted an array of struct, I mean
Well, change the braces to brackets and define the appropriate
constructor, and you're there.
Right.


That doesn't mean it's not worth encapsulating them in properties.
Non-private fields are highly discouraged. You get much more control
and power with properties. You can add in validation etc later, or even
potentially change the underlying type/implementation without callers
caring.

Yes, that's true. I will do this.

Thanks, Jon

Zytan
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Back
Top