anonymous initializer problem

G

Guest

Hi,

I need to initialize my class level dictionary (in .Net 2.0). I wanted to
make it inline and employ anonymous methods as I do not use this code for
anything else. Something similar to the following:

private static Dictionary<string, field> _fields = delegate()
{
Dictionary<string, field> result = new Dictionary<string, field>();
result.Add("Application", new field("Application", "AppName"));
...
return result;
};

And then I need to use the dictionary values in the rest of the declarations.

Apparently the code above does not compile with the error: "Cannot convert
anonymous method block to type
'System.Collections.Generic.Dictionary<string,GroupDates.field>' because it
is not a delegate type".

I understand that it is not - but what is the correct way to initialize a
variable with anonymous method (and is there)?
I could always create a method that would return the correct initialized
object, but would prefer not to.

Any suggestions are appreciated.
 
B

Ben Voigt [C++ MVP]

Sergey Poberezovskiy said:
Hi,

I need to initialize my class level dictionary (in .Net 2.0). I wanted to
make it inline and employ anonymous methods as I do not use this code for
anything else. Something similar to the following:

private static Dictionary<string, field> _fields = delegate()
{
Dictionary<string, field> result = new Dictionary<string, field>();
result.Add("Application", new field("Application", "AppName"));
...
return result;
};

And then I need to use the dictionary values in the rest of the
declarations.

Apparently the code above does not compile with the error: "Cannot convert
anonymous method block to type
'System.Collections.Generic.Dictionary<string,GroupDates.field>' because
it
is not a delegate type".

I understand that it is not - but what is the correct way to initialize a
variable with anonymous method (and is there)?
I could always create a method that would return the correct initialized
object, but would prefer not to.

The C# compiler just puts the initializer code in the static constructor, so
that's what you should do too.

private static readonly Dictionary<string, field> _fields;

static ClassName()
{
_fields = new Dictionary<string, field>();
_fields.Add("Application", new field("Application", "AppName"));
}
 
G

Guest

Ben,

Compiler does not allow putting executable code in the declaration section -
all such code needs to be inside methods/properties :-(
 
G

Guest

Ben,

disregards my previos message - I should have read more carefully - my bad.

Though this is a way to initialize - I wanted to accomplish the
initialization inside the declaration section (before it gets to the static
constructor). The reason for that is that the next lines inside the
costructor declare custom static arrays that use the dictionary values, such
as
private static readonly field[] _REQUIRED_COLUMNS = {_fields["Name1"], ...};
....
private static readonly field[] _CUSTOM_COLUMNS = {_fields["NameN"], ...};

Originally I had just the arrays declarations, and then I noticed that at
times a field name was changed in one array, but not in ALL. As a solution I
created a dictionary to hold the values, so that the change needs to happen
in one place only.

Hope it makes sense
 
B

Ben Voigt [C++ MVP]

Sergey Poberezovskiy said:
Ben,

disregards my previos message - I should have read more carefully - my
bad.

Though this is a way to initialize - I wanted to accomplish the
initialization inside the declaration section (before it gets to the
static
constructor). The reason for that is that the next lines inside the
costructor declare custom static arrays that use the dictionary values,
such
as
private static readonly field[] _REQUIRED_COLUMNS = {_fields["Name1"],
...};
...
private static readonly field[] _CUSTOM_COLUMNS = {_fields["NameN"], ...};

Originally I had just the arrays declarations, and then I noticed that at
times a field name was changed in one array, but not in ALL. As a solution
I
created a dictionary to hold the values, so that the change needs to
happen
in one place only.

Hope it makes sense

If you want to control the order of initialization, you need to put it all
in the static constructor.

Also, I hope that you realize that your readonly arrays are fixed in size,
but not in content. If you need fixed content you should go for something
like ReadonlyCollection.
 
J

Jon Skeet [C# MVP]

If you want to control the order of initialization, you need to put it all
in the static constructor.

That's not strictly true - the spec states that static variable
initializers are executed in the textual order in which they appear in
the class declaration, and all of them are run before the static
constructor. When you've got partial classes, the ordering is less
well defined, admittedly.

I'd say that as a matter of readability and making the system vaguely
robust, I wouldn't want to rely on the order (because someone may
inadvertently change it) but it *should* work according to the spec.

Jon
 
B

Ben Voigt [C++ MVP]

Jon Skeet said:
That's not strictly true - the spec states that static variable
initializers are executed in the textual order in which they appear in
the class declaration, and all of them are run before the static
constructor. When you've got partial classes, the ordering is less
well defined, admittedly.

I'd say that as a matter of readability and making the system vaguely
robust, I wouldn't want to rely on the order (because someone may
inadvertently change it) but it *should* work according to the spec.


I was considering that behavior "too brittle for words", but I now see I am
wrong. There are words...
 
J

Jon Skeet [C# MVP]

I was considering that behavior "too brittle for words", but I now see I am
wrong. There are words...

Oh I certainly wasn't recommending doing it. Just pointing out the
difference between "never ever do this" and "it's not guaranteed to
work". It's guaranteed to work so long as no-one ever touches the code
again :)

Jon
 
B

Ben Voigt [C++ MVP]

Jon Skeet said:
Oh I certainly wasn't recommending doing it. Just pointing out the
difference between "never ever do this" and "it's not guaranteed to
work". It's guaranteed to work so long as no-one ever touches the code
again :)

One might as well check the compiled binary into version control and throw
away the code... less tempting to break it that way.
 
J

Jon Skeet [C# MVP]

Ben Voigt said:
One might as well check the compiled binary into version control and throw
away the code... less tempting to break it that way.

Nearly. On the other hand, it's not exactly infeasible to put big
comments warning what's going on and why. I know I've had brittle code
for "good reason" before now. On the other hand, in this case using a
static constructor is a better way to proceed (unless the slight
performance hit of having a static constructor over just static
initializers is significant, which would be remarkable in itself).
 
G

Guest

Ben,

I do realize that - I use arrays here just so that it is clearly defined in
the declaration section (via initializer). It is just the way I structure my
classes - constants and readonly fields first, then other declarations,
constructors, etc.
This way it is always clear where to go to see/change those definitions -
and that was the reason why I did not want that to be in either constructor
or a static method (which would also work).

At the end I just defined a private class that inherits the typed dictionary
and has only one public constructor that takes an array of field objects.
This way I could define my dictionary in the declaration section where it is
clearly seen:

private class fields : Dictionary<string, field>
{
public fields(field[] array)
{
foreach (field item in array)
{
this.Add(item.Key, item);
}
}
}

private static readonly fields _fields = new fields(
new field[] {
new field("Application", "AppName"),
...
}
);

It is not "anonymous", but is clearly defined in the declaration section -
as I wanted.

Thank you both for your time.

Ben Voigt said:
Sergey Poberezovskiy said:
Ben,

disregards my previos message - I should have read more carefully - my
bad.

Though this is a way to initialize - I wanted to accomplish the
initialization inside the declaration section (before it gets to the
static
constructor). The reason for that is that the next lines inside the
costructor declare custom static arrays that use the dictionary values,
such
as
private static readonly field[] _REQUIRED_COLUMNS = {_fields["Name1"],
...};
...
private static readonly field[] _CUSTOM_COLUMNS = {_fields["NameN"], ...};

Originally I had just the arrays declarations, and then I noticed that at
times a field name was changed in one array, but not in ALL. As a solution
I
created a dictionary to hold the values, so that the change needs to
happen
in one place only.

Hope it makes sense

If you want to control the order of initialization, you need to put it all
in the static constructor.

Also, I hope that you realize that your readonly arrays are fixed in size,
but not in content. If you need fixed content you should go for something
like ReadonlyCollection.
 
?

=?ISO-8859-1?Q?Arne_Vajh=F8j?=

Jon said:
Oh I certainly wasn't recommending doing it. Just pointing out the
difference between "never ever do this" and "it's not guaranteed to
work". It's guaranteed to work so long as no-one ever touches the code
again :)

In general it is not wise to assume that everybody that will have
to maintain the code for the next 10-20 year have memorized the
language specs.

KISS is one of the most important rules.

Arne
 
J

Jon Skeet [C# MVP]

Arne Vajhøj said:
In general it is not wise to assume that everybody that will have
to maintain the code for the next 10-20 year have memorized the
language specs.

KISS is one of the most important rules.

Absolutely - can't (and wouldn't) argue with that. I think we're all in
violent agreement there.
 

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

Top