code:
class Base<T,U> where T:Base<T,U>,new() where U :class
{
protected static U _val = null;
internal static void ShowValue()
{
if(_val == null)new T(); //Without this line, it won't work as expected
Console.WriteLine (_val);
}
internal static void Virtual()
{
Console.WriteLine ("Base");
}
}
class Deriv :Base<Deriv,string>
{
static Deriv()
{
_val = "some string value";
}
internal static new void Virtual ()
{
Console.WriteLine ("Deriv");
}
}
public static void Main (string[] args)
{
Deriv.ShowValue();
Deriv.Virtual();
}
Thanks to the generics of .NET, I can create a bunch of specific classes reusing generic static methods defined in the generic base class. It can mimic inheritance polymorphism to some extent. But in order to initialize different version of static fields, I've to use static constructors. Unfortunately, we can't call them directly, therefore, we have to figure out a way to trigger it's invocation. The example given above showed a way. But I don't like either the instantiation,or the reflection approach. We also can't make a constraint on a static method of a generic parameter. So, I'd like to ask, if there is another way to do this kind of job!
Thanks beforehand!
~~~~~~~~~~~~~~~~
Some Conclusion (Maybe a little early):
It seems there is no workaround to deal with this kind of situation. I have to instantiate a subclass or use reflection. Considering the .cctors need merely be called once, I'm in favor of the reflection approach, because in some case, a new() constraint is just not a choice - like you're not supposed to expose the parameterless ctor to user.
After conducting further experiment, I find out that the .cctors may be called multi-times but only the first invocation will affect the setting of static fields. That's weird, but a good weirdness!
class MyClass
{
static int _val = 0;
static MyClass()
{
_val++;
Console.WriteLine (_val);
}
}
public static void Main (string[] args)
{
ConstructorInfo ci = typeof(MyClass).TypeInitializer;
ci.Invoke(new object[0]);
ci.Invoke(new object[0]);
ci.Invoke(new object[0]);
}
//result:
//1
//1
//1
//1
I would strongly advise you to rethink your design. Attempting to use this sort of workaround for "static inheritance" is fighting against some of the core designs of .NET.
It's unclear what bigger problem you're trying to solve, but trying "clever" code like this to simulate inheritance will lead to code which is very hard to maintain and diagnose in the longer term.
Without actually using a member of Deriv (or creating an instance of it), you basically won't trigger the static constructor. It's important to understand that Deriv.ShowValue() is basically converted into a call to
Base<Deriv, string>.ShowValue();
... so you're not actually calling anything on Deriv. Your calling code would actually be clearer if it were written that way.
EDIT: One other (clearly unfortunate) reason to avoid using type initializers explicitly is that there's a bug in .NET 4.5 which causes an exception to be thrown inappropriately in some cases. See my question on the topic for more information.
The correct solution is to invoke the type initializer (= static constructor) like this:
typeof(T).TypeInitializer.Invoke(null, null);
It needs both nulls. Specifying only one gives a MemberAccessException.
Thus, your code might want to look something like this:
internal static void ShowValue()
{
if (_val == null)
{
if (typeof(T).TypeInitializer != null)
typeof(T).TypeInitializer.Invoke(null, null);
if (_val == null)
throw new InvalidOperationException(string.Format("The type initializer of {0} did not initialize the _val field.", typeof(T)));
}
Console.WriteLine(_val);
}
And with that, you can remove the new() constraint.
You have no control of when the static constuctor will execute, but what is guaranteed is that it will run before accessing any static property or method and before instantiation.
There is really no reason to want the static constructor to execute at an earlier point. If you are not using anything from the class but you want the code in the static constructor to run, then something is wrong in your design.
Static constructors are automatically, only once. You cannot call them yourself.
An example from here:
public class Bus
{
// Static constructor:
static Bus()
{
System.Console.WriteLine("The static constructor invoked.");
}
public static void Drive()
{
System.Console.WriteLine("The Drive method invoked.");
}
}
class TestBus
{
static void Main()
{
Bus.Drive();
}
}
output:
The static constructor invoked.
The Drive method invoked.
I direct you to the MSDN article on Static Constructors and about 10% down the page:
A static constructor is called automatically to initialize the class
before the first instance is created or any static members are
referenced.
Related
I'm trying to use the AutoMapper for model-viewmodel mapping and wanted to have the mapping configuration executed once in the static constructor of the type. The static constructor of a type is not invoked when Mapper.Map (AutoMapper) is invoked with that type.
My understanding is that the Mapper.Map would try to access the type, its members through reflection and on the first attempt of the usage the static constructor would be called. This is something basic but challenges my understanding. The code snippet is provided.
class SampleViewModel
{
static SampleViewModel()
{
Mapper.Initialize(cfg => cfg.CreateMap<Sample, SampleViewModel>().ReverseMap());
}
public SampleViewModel()
{
}
public int PropertyA { get; set; }
public int PropertyB { get; set; }
}
Sample s = new Sample { PropertyA = 10, PropertyB = 20 };
var obj = Mapper.Map<SampleViewModel>(s); // fails
Isn't the static constructor called (if provided) when the type and members are accessed through reflection for the first time?
You're not accessing any members of SampleViewModel - it's not enough to just reference the type itself.
Mapper.Map only accesses its own internal "dictionary" of mappings - before it could ever get to a point where it deals with a SampleViewModel, it fails. The static constructor never runs, so it cannot add "itself" into the Mapper.
Now, if this didn't involve reflection, you would be right that the static constructor would be called - simply because it would happen during the compilation of the method containing the access, e.g.:
var obj = Mapper.Map<SampleViewModel>(s);
Console.WriteLine(obj.SomeField);
In this case, since the method is referencing a field on SampleViewModel, the static constructor for SampleViewModel will be invoked during JIT compilation of the containing method, and as such, the Mapper.Map<SampleViewModel>(s) line will execute correctly, since the mapping is now present. Needless to say this is not the proper solution to your problem. It would just make the code absolutely horrible to maintain :)
DISCLAIMER: Even though this might fix the problem right now, it depends on a non-contractual behaviour in the current implementation of MS.NET on Windows. The contract specifies that the type initializer is invoked before any access to a member of the type, but that still means that a valid implementation of CIL might only call the type initializer after Mapper.Map, as long as it happens before obj.SomeField - and even then, it might be that obj.SomeField gets optimized away if the compiler can ensure it is safe to do so. The only real way to enforce the call of the type initializer is to call RuntimeHelpers.RunClassConstructor, but by that point, you could just as well add a static Init method or something.
The real problem is that you shouldn't really initialize stuff like this in a static constructor in the first place. Mappings should be set in some kind of deterministic initialization process, say, an explicitly invoked InitMappings method. Otherwise you're opening yourself to a huge can of Heisenbugs, not to mention subtle changes in the CLR breaking your whole application for no apparent reason.
Static constructors just aren't meant for "registration", just the initialization of the type itself - anything else is an abuse, and will cause you (or the .NET compatibility team) trouble.
Static constructors run at an implementation-defined time just before the first instance of that class is created, or before any static member of that type is accessed. See When is a static constructor called in C#?.
The mapper tries to find a mapping before doing its work of instantiating the class to map into, and thus can't find a mapping, because the class was never instantiated before that moment.
Just move your mapping initialization code into a AutoMapperBootstrap.cs file or something, and call that in your application initialization.
".. The static constructor of a type is not invoked when Mapper.Map (AutoMapper) is invoked with that type..."
I tested your scenario and observed that the static constructor is indeed being called before the first instance of the object is created.
C# Programming Guide: Static Constructors
I also went ahead and modified the sample code by adding a GetMapper function which returns an IMapper. This might seem like an overkill for day-to-day simple mapping, but if we need an object to give us its mapper, perhaps we can get it from a static method.
One can easily move the responsibility of creating the Mapper object to a factory or a DI container which, for the sake of simplicity, I did not include here.
Worth noting that in this example, the static fields are initialized before the static constructor which is called right after the static read-only fields are initialized.
Uses AutoMapper v12.0 and .Net Core 3.1.
public class SimpleObjectToMap
{
private static readonly MapperConfiguration _simpleObjMapperConfig = new MapperConfiguration(
config => config.CreateMap<SimpleObjectToMap, ObjectToBeMappedTo>());
private static readonly IMapper _mapper = new Mapper(_simpleObjMapperConfig);
private int _propertyA;
public int PropertyA
{
get
{
Console.WriteLine("ObjectToMap.PropertyA.Get");
return _propertyA;
}
set { _propertyA = value; }
}
static SimpleObjectToMap()
{
Console.WriteLine("*** ObjectToMap static ctor called ***");
}
public static IMapper GetMapper()
{
return _mapper;
}
}
public class ObjectToBeMappedTo
{
static ObjectToBeMappedTo()
{
Console.WriteLine("*** ObjectToBeMappedTo static ctor called ***");
}
private int _propertyA;
public int PropertyA
{
get { return _propertyA; }
set
{
Console.WriteLine("ObjectToBeMappedTo.PropertyA.Set");
_propertyA = value;
}
}
}
public class TestObjectMappingWithStaticCtor
{
public void TestWithStaticCtor()
{
SimpleObjectToMap objToMap = new SimpleObjectToMap { PropertyA = 27 };
var mappedObject = SimpleObjectToMap.GetMapper().Map<ObjectToBeMappedTo>(objToMap);
}
}
I'm trying to refactor a method that parses through a file. To support files of arbitrary size, the method using a chunking approach with a fixed buffer.
public int Parse()
{
// Get the initial chunk of data
ReadNextChunk();
while (lengthOfDataInBuffer > 0)
{
[parse through contents of buffer]
if (buffer_is_about_to_underflow)
ReadNextChunk();
}
return result;
}
The pseudo code above is part of the only public non-static method in a class (other than the constructor). The class only exists to encapsulate the state that must be tracked while parsing through a file. Further, once this method has been called on the class, it can't/shouldn't be called again. So the usage pattern looks like this:
var obj = new MyClass(filenameToParse);
var result = obj.Parse();
// Never use 'obj' instance again after this.
This bugs me for some reason. I could make the MyClass constructor private, change Parse to a static method, and have the Parse method new up an instance of Parse scoped to the method. That would yield a usage pattern like the following:
var result = MyClass.Parse(filenameToParse);
MyClass isn't a static class though; I still have to create a local instance in the Parse method.
Since this class only has two methods; Parse and (private) ReadNextChunk, I'm wondering if it might not be cleaner to write Parse as a single static method by embedding the ReadNextChunk logic within Parse as an anonymous method. The rest of the state could be tracked as local variables instead of member variables.
Of course, I could accomplish something similar by making ReadNextChunk a static method, and then passing all of the context in, but I remember that anon methods had access to the outer scope.
Is this weird and ugly, or a reasonable approach?
This maybe suitable more to code review.
However, these are my comments about your design:
I don't think it will matter much about obj instance only used once. If you bugged with it, there are 2 ways to trick it:
Use of another method such as:
public int Parse()
{
var obj = new MyClass(filenameToParse);
return obj.Parse();
}
Make the MyClass implement IDisposable and wrap it in using statement. I don't recommend this since usually IDisposable has logic in their Dispose() method
I think it is better to make your MyClass accept parameter in Parse to Parse(string fileNameToParse). It will make MyClass as a service class, make it stateless, reusable and injectable.
Regarding impact to static class. First it add coupling between your consumer and MyClass. Sometimes if you want to test / unit test the consumer without using the MyClass parser, it will be hard / impossible to mock the MyClass into something you want.
All you need is a static parse method that creates an instance, much like what you suggest in your question
public class MyClass
{
// your existing code.... but make the members and constructor private.
public static int Parse(string filenameToParse)
{
return new MyClass(filenameToParse).Parse();
}
}
then
just use it like you suggest...
var result = MyClass.Parse(filenameToParse);
MyClass isn't a static class though; I still have to create a local
instance in the Parse method.
You don't need a static class to be able to leverage static methods. For example this works fine:
public class MyClass
{
public static string DoStuff(string input)
{
Console.WriteLine("Did stuff: " + input);
return "Did stuff";
}
}
public class Host
{
public void Main()
{
MyClass.DoStuff("something");
}
}
I want to write unit test for below class.
If name is other than "MyEntity" then mgr should be blank.
Negative Unit test
Using Manager private accessor I want to change name to "Test" so that mgr should be null.
And then will verify the mgr value.
To achieve this, I want to explicitly call the static constructor
but when I call the static constructor using
Manager_Accessor.name = "Test"
typeof(Manager).TypeInitializer.Invoke(null, null);
name is always set to "MyEntity" how to set name to "Test" and invoke the static constructor.
public class Manager
{
private static string name= "MyEntity";
private static object mgr;
static Manager()
{
try
{
mgr = CreateMgr(name);
}
catch (Exception ex)
{
mgr=null;
}
}
}
As I found out today, the static constructor CAN be called directly:
from another Stackoverflow post
The other answers are excellent, but if you need to force a class
constructor to run without having a reference to the type (ie.
reflection), you can use:
Type type = ...;
System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor(type.TypeHandle);
I had to add this code to my application to work around a possible bug in the .net 4.0 CLR.
For anyone finding this thread and wondering... I just did the test. It appears System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor() will only run the static constructor if it has not already been run for another reason.
For example, if your code isn't positive whether or not previous code may have accessed the class and triggered the static constructor to run, it doesn't matter. That previous access will have triggered the static constructor to run, but then RunClassConstructor() will not run it also. RunClassConstructor() only runs the static constructor if it hasn't already been run.
Accessing the class after RunClassConstructor() also does not result in the static constructor being run a second time.
This is based on testing in a Win10 UWP app.
Just add public static void Initialize() { } method to your static class and call it when you want. This is very similar to call constructor, because static constructor will be called automatically.
If you have a static member in your class (there must be, otherwise static constructor wouldn't do too much) then no need to explicitly call the static constructor.
Simply access the class where you would like to call its static constructor.
E.g.:
public void MainMethod()
{
// Here you would like to call the static constructor
// The first access to the class forces the static constructor to be called.
object temp1 = MyStaticClass.AnyField;
// or
object temp2 = MyClass.AnyStaticField;
}
Im currently trying to build a Fluent Interface for a ServiceLocator. To ensure that each the developer can easily setup 1-to-n mappings
I'd like something like this
ServiceLocator.Instance.For<IFoo>(Use<Foo>(), Use<FooBar>());
Singleton is workin fine... the methodsignature for the For method looks like this
public void For<TInterface>(params type[] services)
{
// ...
}
So I was looking for something like a global method
C# has some global methods, all methods which are defined on System.Object. But when I create a new generic ExtensionMethod on System.Object, the method will not be visible.
public static class MyExtensions
{
public static void Use<T>(this Object instance)
{
// ..
}
}
MethodChaining would be the alternative, but this approach looks sexy :D
Has anyone an idea?
Well, actually when I create an extension method for Object, it is visible. As in,
public static class Extensions
{
public static void doStuff<T>(this T myObject)
{
}
}
class Program
{
static void Main(string[] args)
{
int a = 5;
a.doStuff();
string b = "aaa";
b.doStuff();
List<int> c = new List<int>() { 1, 2, 3, 10 };
c.doStuff();
Extensions.doStuff(c);
}
}
Did I misunderstand your question?
You need to add a using statement for the namespace containing your extension method in order for it to be visible. Adding extension methods to object is rarely a good idea.
EDIT:
Okay, now I understand what you're asking. In order to use an extension method you need an instance. You're asking for a static extension method on object (Equals and ReferenceEquals are static methods), and that's not possible. If you define an extension method on object, it will be available on all instances and I'm sure that's not what you want.
public static class ObjectExtensions
{
public static string TypeFullName(this object obj)
{
return obj.GetType().FullName;
}
}
static void Main(string[] args)
{
var obj = new object();
Console.WriteLine(obj.TypeFullName());
var s = "test";
Console.WriteLine(s.TypeFullName());
}
Service Locator is widely considered to be an anti-pattern. Also, a common registration interface is widely considered to be an unsolvable problem unless you are requiring use of a specific container.
Looking past these two questionable decisions, you can remove the need for the global method by defining overloads of For which accept multiple type arguments:
ServiceLocator.Instance.For<IFoo, Foo, FooBar>();
The For methods would look like this:
public void For<TInterface, TImplementation>()
public void For<TInterface, TImplementation1, TImplementation2>()
...
You have to define an overload for each type count, but it requires the minimal syntax and maximum amount of discoverability. For reference, the .NET Framework's Action and Func types support 9 type arguments.
After writing this out, though, I wonder if I misunderstood the question: why would you specify multiple implementations for the same interface? Wouldn't that lead to ambiguity when resolving IFoo?
I have requirement in which, I have to call some initializing method before the call of any static method in the class.
Now the problem is that whenever i add new static method to that class, I forget to call that initializing method, I was wondering if there any design pattern to solve this problem. I want the initializing method is always called whenever a static method is called from the class.
AOP might be an overkill for this problem. What you may want to try is to delegate each of the static methods to another class and add the initialization code to the constructor of that class. Something like:
class StaticClass {
public static void m1 () {
new Worker().m1();
}
public static void m2 () {
new Worker().m2();
}
}
class Worker {
public Worker() {
intialize();
}
public void m1() {
// Real m1 work
}
public void m2() {
// Real m2 work
}
}
This atleast solves the problem of forgetting to put in the call to init code.
That said, this looks like: https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem
Can you step back and tell us why you need this?
Something like Spring AOP addresses this situation pretty well for Java. It uses AspectJ annotations to make things a little simpler, although personally I think AOP is fairly complex.
Java has static initialization blocks. Something like this:
public class SomeClass {
static {
// Your code here
}
}