Previously I've had a static TopUp() method what I wanted to substitute with the Baseclass's static constructor, because it's "performed once only" as the msdn states.
msdn: Static Constuctor
Any solution for keep the derived classes' initialization in the constructor and perform it only once?
class BaseClass<T>
{
static BaseClass()
{
for (byte i = 0; i < 2; i++)
{
var temp = new Junction<byte>[2] { new Level2<byte>(), new OtherLevel2<byte>() };
Program.myList.Add(temp);
}
Console.WriteLine("static BaseClass()");
}
}
abstract class Junction<T> : BaseClass<T> { }
sealed class Level2<T> : Junction<T> { }
sealed class OtherLevel2<T> : Junction<T> { }
class Program
{
internal static List<Junction<byte>[]> myList = new List<Junction<byte>[]>();
static Program()
{
BaseClass<object> callTheStaticMethod = new BaseClass<object>();
}
static void Main()
{
Console.WriteLine("myList.Count = " + myList.Count);
Console.ReadLine();
}
}
Output:
static BaseClass()
static BaseClass()
myList.Count = 4
Your static construction is called only once. Once per type, that is.
Each time you use your BaseClass<T> with a different type parameter, that's a completely different type. So, Junction<byte>, which inherits BaseClass<byte>, is a different type from BaseClass<object>. The static constructor for BaseClass<byte> is called, as well as the static constructor for BaseClass<object>.
It's not really clear from your question what it is you're actually trying to achieve. I will say, that the use of Junction<byte> in the static constructor strongly suggests that your class is not really generic at all. Any other use of BaseClass<T> is necessarily still dependent on Junction<byte>, and thus BaseClass<byte>. And this probably negates whatever benefit you thought you were going to get by making the class generic.
You can force the static constructor to execute only once by moving it to a non-generic base class inherited by BaseClass<T>. E.g.:
class BaseClass { /* static constructor here */ }
class BaseClass<T> : BaseClass { /* other stuff */ }
But given the lack of generic-ness in the class to start with, it's not clear that this will really help much. There seems to be a broader design flaw here that should be addressed.
The issue is that you have the static initializer in a typed base class. The issue is that BaseClass<string> and BaseClass<int> are considered two different types. The actual classes are generated at compile time, and so the compiler duplicates the static initializer for each variation.
If you change the last line in the static initializer to include the name of the type you'll be able to get a better idea of this issue.
In .Net 4.6 you can do this:
Console.WriteLine($"static BaseClass<{nameof(T)}>()");
In .Net 4.0 or later you can do this:
string typeName = typeof(T).FullName;
Console.WriteLine(string.Format("static BaseClass<{0}>()", typeName));
To resolve your issue, do your static initialization in a standard class that does not have a type parameter. In this case, you can simply remove the <T> type parameter from the BaseClass. Example:
class BaseClass
{
static BaseClass()
{
for (byte i = 0; i < 2; i++)
{
var temp = new Junction<byte>[2] { new Level2<byte>(), new OtherLevel2<byte>() };
Program.myList.Add(temp);
}
Console.WriteLine($"static BaseClass<{nameof(T)}>()");
}
}
abstract class Junction<T> : BaseClass { }
sealed class Level2<T> : Junction<T> { }
sealed class OtherLevel2<T> : Junction<T> { }
Related
I want to force my child classes to pass themselves as as the generic parameter to the parent class.
For example :
class BaseClass<T> where T: BaseClass
{
//FullClassName : Tuple [Save,Update,Delete]
Dictionary<string,Tuple<delegate,delegate,delegate>> dict = new Dictionary...;
static BaseClass()
{
RegisterType();
}
private static void RegisterType()
{
Type t = typeof(T);
var props = t.GetProperties().Where(/* Read all properties with the SomeCustomAttribute */);
/* Create the delegates using expression trees and add the final tuple to the dictionary */
}
public virtual void Save()
{
delegate d = dict[t.GetType().FullName];
d.Item1(this);
}
}
class ChildClass : BaseClass<ChildClass>
{
[SomeCustomAttribute]
public int SomeID {get;set;}
[SomeCustomAttribute]
public string SomeName {get; set;}
}
public class Program
{
public static void Main(string[] args)
{
ChildClass c = new ChildClass();
c.Save();
}
}
Obviously the above code won't compile. I'll restate : I want the child class to pass itself as the generic parameter and not any other child of BaseClass.
(The above code is kind of a psuedo code and will still not compile).
You can do this:
public class BaseClass<T> where T: BaseClass<T> { }
public class ChildClass : BaseClass<ChildClass> { }
But this doesn't force you to use ChildClass as the generic parameter. You could do this public class OtherChildClass : BaseClass<ChildClass> { } which would break the "coontract" that you want to enforce.
The direct answer is that if your accessing a static method then typeof(T) will give you the type for reflection.
However, there is probably better solutions than using reflection. Options:
1) Static constructor on the child class.
2) Abstract method declared in the base class.
I do not know the application, but I get concerned about my design if I feel like using a static constructor, I also get concerned if a base class needs to initialize the child class.
I suggest looking at injection as a solution rather than inheritance. It offers superior unit testing and often a better architecture.
More info (after initial post), this is my preferred solution:
public interface IRegesterable
{
void Register();
}
public class Widget : IRegesterable
{
public void Register()
{
// do stuff
}
}
public class Class1
{
public Class1(IRegesterable widget)
{
widget.Register();
}
}
Hope this helps
The ConcurrentDictionary is being used as a Set<Type>. We can check in the Set<Type> if the type has been initialized. If not we run RegisterType on the type.
public abstract class BaseClass
{
//Concurrent Set does not exist.
private static ConcurrentDictionary<Type, bool> _registeredTypes
= new ConcurrentDictionary<Type, bool>();
protected BaseClass()
{
_registeredTypes.GetOrAdd(GetType(), RegisterType);
}
private static bool RegisterType(Type type)
{
//some code that will perform one time processing using reflections
//dummy return value
return true;
}
}
public class ChildClass : BaseClass
{
}
There are several inefficiencies with this pattern though.
object.GetType() is pretty darn slow, and inefficient.
Even with the HashSet behavior, we are checking for initialization on each instanciation. Its as fast as I can get it, but its still pretty superfluous.
I have a class library which contain some base classes and others that are derived from them. In this class library, I'm taking advantage of polymorphism to do what I want it to do. Now in a consuming application, I want to change the behavior of some code based on the runtime type of the child classes. So assume the following:
public class Base { }
public class Child1 : Base { }
public class Child2 : Base { }
Now in the consuming application I want do something as follows (note that all of the following classes are in the consuming application and cannot be referenced in the class library):
public interface IMyInterface1 { }
public interface IMyInterface2 { }
public static class Extensions
{
public static void DoSomething(this Base myObj, Object dependency)
{
}
public static void DoSomething(this Child1 myObj, Object dependency)
{
IMyInterface1 myInterface = dependency as IMyInterface1;
if (myInterface != null)
{
//Do some Child1 specific logic here
}
}
public static void DoSomething(this Child2 myObj, Object dependency)
{
IMyInterface2 myInterface = dependency as IMyInterface2;
if (myInterface != null)
{
//Do some Child2 specific logic here
}
}
}
UPDATE:
This does not work. It always calls the extension method of the base class. Is there some other way that will allow me to do this and avoid having to explicitly check for the runtime type? The reasons is because more classes that are derived from the Base could be added and corresponding extension methods could come from some other external assembly.
Thanks in advance.
As #SLaks has already stated you cannot call the method as an extension method (even with a dynamic type) ... you can however call the static method with a dynamic type
So, although this will fail
Base base1 = new Child1();
(base1 as dynamic).DoSomething();
This will work
Base base1 = new Child1();
Extensions.DoSomething(base1 as dynamic);
No, that won't work.
Extension methods are statically dispatched, using the same mechanism as overload resolution.
If you have a variable of compile-time type Base, the compiler will always call the base extension method, regardless of the runtime type.
Instead, you can make the base extension method check the runtime type and call the appropriate other extension method.
I was looking for the same thing just now.
You could add one more method to your extension class like this:
public static void DoSomething(this Base myObj, Object dependency)
{
if(myObj.IsSubclassOf(Base))
{
// A derived class, call appropriate extension method.
DoSomething(myObj as dynamic, dependency);
}
else
{
// The object is Base class so handle it.
}
}
You don't need the if/else check if the base class is abstract (or never used in the wild):
public static void DoSomething(this Base myObj, Object dependency)
{
DoSomething(myObj as dynamic, dependency);
}
[Edit] Actually this won't work in your case as you don't implement support for all derived objects (so could still get infinite recursion). I guess you could pass something to check for recursion but the given answer is the simplest. I'll leave this here as it might spark more ideas.
Below is the minimal example showing how to mimic polymorphism with extension methods.
void Main()
{
var elements = new Base[]{
new Base(){ Name = "Base instance"},
new D1(){ Name = "D1 instance"},
new D2(){ Name = "D2 instance"},
new D3(){ Name = "D3 instance"}
};
foreach(Base x in elements){
x.Process();
}
}
public class Base{
public string Name;
}
public class D1 : Base {}
public class D2 : Base {}
public class D3 : Base {}
public static class Exts{
public static void Process(this Base obj){
if(obj.GetType() == typeof(Base)) Process<Base>(obj); //prevent infinite recursion for Base instances
else Process((dynamic) obj);
}
private static void Process<T>(this T obj) where T: Base
{
Console.WriteLine("Base/Default: {0}", obj.Name);
}
public static void Process(this D1 obj){
Console.WriteLine("D1: {0}", obj.Name);
}
public static void Process(this D2 obj){
Console.WriteLine("D2: {0}", obj.Name);
}
}
Outputs:
Base/Default: Base instance
D1: D1 instance
D2: D2 instance
Base/Default: D3 instance
If you can not use the keyword "dynamic" (older version of .NET), you can use reflection to achieve the same thing.
In place of :
Base base1 = new Child1();
Extensions.DoSomething(base1 as dynamic);
you can write :
Base base1 = new Child1();
MethodInfo method = typeof(Extensions).GetMethod("DoSomething", new System.Type[] { base1.GetType() });
if (method) {
method.Invoke(new object[] { base1 });
}
i'm writing some ashx handlers which are wired to a mock service, and i want them to share the mock service instance. The simplest approach i though was creating a static instance
public class AbstractHandler
{
static IService _impl;
public static IService Impl
{
get
{
if (_impl == null)
{
_impl = new MockService();
}
return _impl;
}
}
}
However, i'm wondering if this is going to work at all; will different handlers that inherit from this class will have their own static _impl reference or they will be shared?
A static field exists once, except in the case of a generic type, in which case it exists once for each used combination of generic parameters.
Even if the class is a base class, possibly abstract, the same rules apply. Note that if the class in which the field is declared is not generic, the field will exist once, even if descendants are generic. The rule about "once per combination ..." only comes into play if the class that declares the static field is generic.
So, if your question instead had been:
How can I make the static field be per descendant and not just once
Then the answer would've been that you should make your base class generic, and pass the descendant type as the generic parameter.
Example LINQPad script to demonstrate the "once per generic parameter combination":
void Main()
{
var i = new Test<int>();
var s = new Test<string>();
Test<bool>.UsageCount.Dump();
Test<int>.UsageCount.Dump();
Test<string>.UsageCount.Dump();
}
public class Test<T>
{
public static int UsageCount;
public Test()
{
UsageCount++;
}
}
Output:
0
1
1
Example to demonstrate with base class:
void Main()
{
var i = new Test1();
var s = new Test2();
Test1.UsageCount.Dump();
Test2.UsageCount.Dump();
Test3.UsageCount.Dump();
}
public abstract class Base<T>
{
public static int UsageCount;
protected Base()
{
UsageCount++;
}
}
public class Test1 : Base<Test1>
{
}
public class Test2 : Base<Test2>
{
}
public class Test3 : Base<Test3>
{
}
Output:
1
1
0
The documentation on static constructors in C# says:
A static constructor is used to
initialize any static data, or to
perform a particular action that needs
performed once only. It is called
automatically before the first
instance is created or any static
members are referenced.
That last part (about when it is automatically called) threw me for a loop; until reading that part I thought that by simply accessing a class in any way, I could be sure that its base class's static constructor had been called. Testing and examining the documentation have revealed that this is not the case; it seems that the static constructor for a base class is not guaranteed to run until a member of that base class specifically is accessed.
Now, I guess in most cases when you're dealing with a derived class, you would construct an instance and this would constitute an instance of the base class being created, thus the static constructor would be called. But if I'm only dealing with static members of the derived class, what then?
To make this a bit more concrete, I thought that the code below would work:
abstract class TypeBase
{
static TypeBase()
{
Type<int>.Name = "int";
Type<long>.Name = "long";
Type<double>.Name = "double";
}
}
class Type<T> : TypeBase
{
public static string Name { get; internal set; }
}
class Program
{
Console.WriteLine(Type<int>.Name);
}
I assumed that accessing the Type<T> class would automatically invoke the static constructor for TypeBase; but this appears not to be the case. Type<int>.Name is null, and the code above outputs the empty string.
Aside from creating some dummy member (like a static Initialize() method that does nothing), is there a better way to ensure that a base type's static constructor will be called before any of its derived types is used?
If not, then... dummy member it is!
You may call static constructor explicity, so you will not have to create any methods for initialization:
System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor(typeof (TypeBase).TypeHandle);
You may call it in static constructor of derived class.
As others have noted, your analysis is correct. The spec is implemented quite literally here; since no member of the base class has been invoked and no instance has been created, the static constructor of the base class is not called. I can see how that might be surprising, but it is a strict and correct implementation of the spec.
I don't have any advice for you other than "if it hurts when you do that, don't do that." I just wanted to point out that the opposite case can also bite you:
class Program
{
static void Main(string[] args)
{
D.M();
}
}
class B
{
static B() { Console.WriteLine("B"); }
public static void M() {}
}
class D: B
{
static D() { Console.WriteLine("D"); }
}
This prints "B" despite the fact that "a member of D" has been invoked. M is a member of D solely by inheritance; the CLR has no way of distinguishing whether B.M was invoked "through D" or "through B".
The rules here are very complex, and between CLR 2.0 and CLR 4.0 they actually changed in subtle and interesting ways, that IMO make most "clever" approaches brittle between CLR versions. An Initialize() method also might not do the job in CLR 4.0 if it doesn't touch the fields.
I would look for an alternative design, or perhaps use regular lazy initialization in your type (i.e. check a bit or a reference (against null) to see if it has been done).
In all of my testing, I was only able to get a call to a dummy member on the base to cause the base to call its static constructor as illustrated:
class Base
{
static Base()
{
Console.WriteLine("Base static constructor called.");
}
internal static void Initialize() { }
}
class Derived : Base
{
static Derived()
{
Initialize(); //Removing this will cause the Base static constructor not to be executed.
Console.WriteLine("Derived static constructor called.");
}
public static void DoStaticStuff()
{
Console.WriteLine("Doing static stuff.");
}
}
class Program
{
static void Main(string[] args)
{
Derived.DoStaticStuff();
}
}
The other option was including a static read-only member in the derived typed that did the following:
private static readonly Base myBase = new Base();
This however feels like a hack (although so does the dummy member) just to get the base static constructor to be called.
I almost alway regret relying on something like this. Static methods and classes can limit you later on. If you wanted to code some special behavior for your Type class later you would be boxed in.
So here is a slight variation on your approach. It is a bit more code but it will allow you to have a custom Type defined later that lets you do custom things.
abstract class TypeBase
{
private static bool _initialized;
protected static void Initialize()
{
if (!_initialized)
{
Type<int>.Instance = new Type<int> {Name = "int"};
Type<long>.Instance = new Type<long> {Name = "long"};
Type<double>.Instance = new Type<double> {Name = "double"};
_initialized = true;
}
}
}
class Type<T> : TypeBase
{
private static Type<T> _instance;
public static Type<T> Instance
{
get
{
Initialize();
return _instance;
}
internal set { _instance = value; }
}
public string Name { get; internal set; }
}
Then later when you get to adding a virtual method to Type and want a special implementation for Type you can implement thus:
class TypeInt : Type<int>
{
public override string Foo()
{
return "Int Fooooo";
}
}
And then hook it up by changing
protected static void Initialize()
{
if (!_initialized)
{
Type<int>.Instance = new TypeInt {Name = "int"};
Type<long>.Instance = new Type<long> {Name = "long"};
Type<double>.Instance = new Type<double> {Name = "double"};
_initialized = true;
}
}
My advice would be to avoid static constructors - it is easy to do. Also avoid static classes and where possible static members. I am not saying never, just sparingly. Prefer a singleton of a class to a static.
Just an idea, you can do something like this:
abstract class TypeBase
{
static TypeBase()
{
Type<int>.Name = "int";
Type<long>.Name = "long";
Type<double>.Name = "double";
}
}
class Type<T> : TypeBase
{
static Type()
{
new Type<object>();
}
public static string Name { get; internal set; }
}
class Program
{
Console.WriteLine(Type<int>.Name);
}
I have a class in C# with a template and static method similar to
class BClass<T>
{
public static BClass<T> Create()
{
return new BClass<T>();
}
}
From this I derive a class and specify a template parameter to the base class
class DClass : BClass<int> { }
A problem occurs when I try to use the static method to create an instance of D
class Program
{
static void Main(string[] args)
{
DClass d = DClass.Create();
}
}
Gives a compiler error "Cannot implicitly convert type 'Test.BClass<int> ' to 'Test.DClass'."
Adding the below cast leads to a runtime casting exception.
DClass d = (DClass)DClass.Create();
Is there any succint way to allow the static method to create instances of the derived class? Ideally I would like the equivalent of a c++ typedef and I don't want the below syntax (which does work).
BClass<int> d = DClass.Create();
It seems that what you want is for DClass to be an alias for BClass<int>. But that's not what you have here. What you have is that DClass derives from BClass<int>. Thus calling DClass.Create(); creates a BClass<int>, which is not a DClass (it's the other way around).
This might make it clearer. Suppose you had this hierarchy:
class Rectangle {
static Rectangle Create() {
return new Rectangle();
}
}
class Square : Rectangle { }
// code elsewhere
var shape = Square.Create(); // you might want this to return a square,
// but it's just going to return a rectangle
One option to get something like the functionality you want might be to define your Create method like this:
static TClass Create<TClass>() where TClass : BClass<T>, new() {
return new TClass();
}
// code elsewhere
var shape = DClass.Create<DClass>();
That's a bit messy, though (and also requires that you write a parameterless constructor for DClass). If you're dead set on using a Create method for the instantiation of your objects, consider writing a factory class for it.
Yes it is possible, by having a type reference to the type itself. Note that in the .NET world we are talking of generics, not templates, which do have important differences in the way they work.
class BClass<T, TSelf> where TSelf: BClass<T, TSelf>, new() {
public static TSelf Create() {
return new TSelf();
}
}
class DClass: BClass<int, DClass> {}
class Program {
static void Main(string[] args) {
DClass d = DClass.Create();
}
}
class BClass<T>
{
public static T1 Create<T1, T2>() where T1 : BClass<T2>, new()
{
return new T1();
}
}
class DClass : BClass<int> { }
class Program
{
static void Main(string[] args)
{
DClass d = DClass.Create<DClass, int>();
}
}