C# generic type

W

webcliff

Please help me to look at the following code:

-------------start----------
using System;
using System.Collections.Generic;

public class GenType
{
}

public class GenericType1<T> where T : new()
{
public static T Instance
{
get
{
return new T();
}
}

protected static string SECTION_ID;
}

public class GenericType2<T>
: GenericType1<T> where T : new()
{
public static T Load()
{
return Instance;
}
}

public sealed class Alpha
: GenericType2<GenType>
{
static Alpha()
{
Console.WriteLine("static ctor called.");
SECTION_ID = "Alpha";
}
}

public class Test
{
public static void Main()
{
GenType o = Alpha.Load();
}
}
-------------end----------

When I run the compiled code, I don't see "static ctor called." in
output (I am not sure why not).

I intend to implement most of the code in base generic class, only
pass some values (e.g. SECTION_ID) to base class from children class
(e.g. Alpha). Instance and Load() have to be static, do you guys have
any solution?
 
J

Jon Skeet [C# MVP]

webcliff said:
Please help me to look at the following code:

When I run the compiled code, I don't see "static ctor called." in
output (I am not sure why not).

This is nothing to do with being generic - if you have two classes,
"Base" and "Derived" and a static method in "Base" called
MyStaticMethod, then a call to Derived.MyStaticMethod will be compiled
as Base.MyStaticMethod - which means that the static constructor for
Derived won't get called at that point.
I intend to implement most of the code in base generic class, only
pass some values (e.g. SECTION_ID) to base class from children class
(e.g. Alpha). Instance and Load() have to be static, do you guys have
any solution?

If you want to initialize a whole bunch of classes at a particular
point in time, it's probably best to do so in some other way - such as
by having an attribute on each type that needs to be initialized, and
run through such types with reflection.

Note that you only get one SECTION_ID variable per parameter type
argument used - so if any other class derived (directly or indirectly)
from GenericType1<GenType> and changed SECTION_ID, you'd have problems.
 
W

webcliff

This is nothing to do with being generic - if you have two classes,
"Base" and "Derived" and a static method in "Base" called
MyStaticMethod, then a call to Derived.MyStaticMethod will be compiled
as Base.MyStaticMethod - which means that the static constructor for
Derived won't get called at that point.

m... I didn't know that, but I still wonder why the compiler want to
do this,
it is a suprise.
If you want to initialize a whole bunch of classes at a particular
point in time, it's probably best to do so in some other way - such as
by having an attribute on each type that needs to be initialized, and
run through such types with reflection.

Classes like Alpha are auto-generated types.
What I really want is something like a parameterized generic type, I
can create
a type (i.e. Alpha) with a type GenType and a string:

public Alpha : GenericType1<GenType, "my id">

I am guessing this is not something DOTNET generic would like to do.

Note that you only get one SECTION_ID variable per parameter type
argument used - so if any other class derived (directly or indirectly)
from GenericType1<GenType> and changed SECTION_ID, you'd have problems.

thanks for reminding.
 
W

webcliff

m... I didn't know that, but I still wonder why the compiler want to
do this, it is a suprise.

The meaning of "static" is that the complete information is known at
compilation time - it is statically called rather than dynamically
called. The compiler has determined that the static method in the base
class should be called, so that's the code that it emits.
Classes like Alpha are auto-generated types.

In that case you could create a static method in the auto-generated
type
which calls the static method in the base type.
What I really want is something like a parameterized generic type, I
can create
a type (i.e. Alpha) with a type GenType and a string:

public Alpha : GenericType1<GenType, "my id">

I am guessing this is not something DOTNET generic would like to do.

No, you can't do that.

Jon
 

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