I understand how in C# closures allow access to private variables declared in the same scope as an anonymous method, so that those variables are available when the method is invoked in a different scope.
But what about private constructors? This code works:
class Program
{
static void Main(string[] args)
{
var someClassFactory = SomeClass.GetFactoryMethod();
var someclass = someClassFactory();
}
}
class SomeClass
{
private SomeClass()
{
}
public static Func<SomeClass> GetFactoryMethod()
{
return () => new SomeClass();
}
}
As the compiler creates a class for the closure, how does it then reference the private constructor, or otherwise allow it to be accessed when the anonymous method is invoked by the client code?
In this case, the compiler doesn't need to create a class at all - it can just create a static method:
public static Func<SomeClass> GetFactoryMethod()
{
return __GeneratedMethod;
}
private static SomeClass __GeneratedMethod()
{
return new SomeClass();
}
Even when it does need to generate a class - e.g. if GetFactoryMethod() had a parameter which was captured by the lambda expression - it would generate a nested class, and nested classes have access to the private members of their enclosing classes:
public class Foo
{
private Foo() {}
public class Bar
{
public Foo MakeNewFoo()
{
return new Foo(); // This is absolutely fine
}
}
}
Related
Suppose I have these 2 classes:
public class A<T> where T : IEntityWithID, new()
{
private static EntityInfo entityInfo = B.GetEntityInfo(typeof(T));
private static IEnumerable TestCases
{
// Do work with entityInfo...
}
}
private static class B
{
private static IList<EntityInfo> entityInfoList = B.GetEntityList();
public static EntityInfo GetEntityInfo(Type type)
{
return entityInfoList.Single(e => e.Types.Contains(type));
}
private static IList<EntityInfo> GetEntityList()
{
// Builds a list of EntityInfo's...
}
}
Is the entityInfoList in class B guaranteed to be initialized and populated before B.GetEntityInfo() is called in class A?
Yes, it is guaranteed. Here's a snippet from MSDN:
The program cannot specify exactly when the class is loaded. However,
it is guaranteed to be loaded and to have its fields initialized and
its static constructor called before the class is referenced for the
first time in your program.
EDIT: As pointed out, you could end up in a situation where 2 static classes depend on each other for initialization which could get you in trouble, but as long as that's not the case, you're fine.
No, if you have circular dependencies it's possible to run code from a class before that class's static initialization has finished.
Here's a simple example of a static field initialized to 5, and yet an external class observes that field being null:
public class A
{
public static void Foo()
{
Console.WriteLine(B.bar == null);
}
}
public class B
{
public static readonly object bar = Foo();
public static object Foo()
{
A.Foo();
return 5;
}
}
private static void Main(string[] args)
{
var bar = B.bar;
}
This will print true.
I have couple of question regarding Static Constructor in C#.
What exactly are Static Constructor and how they are different from non-static Constructor.
How can we use them in our application ?
**Edited
public class Test
{
// Static constructor:
static Test()
{
Console.WriteLine("Static constructor invoked.");
}
public static void TestMethod()
{
Console.WriteLine("TestMethod invoked.");
}
}
class Sample
{
static void Main()
{
Test.TestMethod();
}
}
Output :
Static constructor invoked.
TestMethod invoked.
So, this means that static constructor will be called once. if we again call Test.TestMethod(); static constructor won't invoke.
Any pointer or suggestion would be appreciated
'
Thanks
Static constructors are constructors that are executed only ONCE when the class is loaded. Regular (non-static) constructors are executed every time an object is created.
Take a look at this example:
public class A
{
public static int aStaticVal;
public int aVal;
static A() {
aStaticVal = 50;
}
public A() {
aVal = aStaticVal++;
}
}
And consider this code:
A a1 = new A();
A a2 = new A();
A a3 = new A();
Here, static constructor will be called first and only once during the execution of the program. While regular constructor will be called three times (once for each object instantiation).
static constructors are usually used to do initialization of static fields for example, assigning an initial value to static fields.. Do keep in mind that you will only be able to access static members (methods, properties and fields) on static constructors.
If you need to "execute the static constructor multiple times", you can't do that. Instead, you can put the code you want to run "multiple times" in a static method and call it whenever you need. Something like:
public class A {
public static int a, b;
static A() {
A.ResetStaticVariables();
}
public static void ResetStaticVariables() {
a = b = 0;
}
}
You use them the same way you use instance constructors - to set default values. Only in this case you'll be initializing static fields, so static constructors get executed only once.
Be aware that the code in static constructor won't be executed until the first call to the class was made.
it runs when class is loaded.
It will print :
{
hi from static A
A
}
public class A{
static A{
print("hi from static A");
}
public A() {
print("A");
}
main() {
new A();
}
}
why i generate instance outside of class. i give inheritance snifC to sinifD i need to create instance sinifC sinifc= new sinifC() in SinifD out side of constructor?
public class sinifC
{
public void method3()
{
Console.WriteLine("Deneme3");
}
}
public class sinifD : sinifC
{
void method4()
{
Console.WriteLine("Deneme4");
}
public sinifD()
{
sinifC sinifc = new sinifC();
sinifc.method3();
}
}
i want to make it below:
public class sinifC
{
public void method3()
{
Console.WriteLine("Deneme3");
}
}
public class sinifD : sinifC
{
void method4()
{
Console.WriteLine("Deneme4");
}
sinifC sinifc = new sinifC();
sinifc.method3();
}
Error: Invalid token '(' in class, struct, or interface member declaration
doesn't
sinifC sinifc = new sinifC();
sinifc.method3();
need to be inside a method?
You seem to want to create an instance of an object and call its method inside the body of the class, but you need to have it happen inside a method.
You don't have to write the code in the constructor, but you do have to write the code in some method. You're currently just writing the code anywhere in your class. If you don't want to have to create an instance of your D class to do this you could create a static method in your D class that creates the instance of the C class (you could even have a static constructor).
The only valid instructions in the body of a class are declarations (optionally including initialization for fields). A method call is not a valid instruction here, it has to be inside a method
You do not need to create an instance of sinifC - you are using inheritace by extending it.
class Program
{
static void Main(string[] args)
{
sinifD s = new sinifD();
// call method3 on sinfiD
s.method3();
}
}
public class sinifC
{
public void method3()
{
Console.WriteLine("Deneme3");
}
}
public class sinifD : sinifC
{
// sinifD inheritrs mehtod3 from sinifD
// method 4 is protected, so only classes in the class hierachy see that method
void method4()
{
Console.WriteLine("Deneme4");
}
}
As far as I know you can can't pass parameters to a static constructor in C#.
However I do have 2 parameters I need to pass and assign them to static fields before I create an instance of a class. How do I go about it?
This may be a call for ... a Factory Method!
class Foo
{
private int bar;
private static Foo _foo;
private Foo() {}
static Foo Create(int initialBar)
{
_foo = new Foo();
_foo.bar = initialBar;
return _foo;
}
private int quux;
public void Fn1() {}
}
You may want to put a check that 'bar' is already initialized (or not) as appropriate.
You can't pass parameters to a static constructor, but you can pass parameters to the class itself - via generic type parameters.
Slightly crazy this idea, however, I'll just throw it out there anyway.
Make the class generic (with a TypeParam that will provide a parameter type) and place generic constraints on it (details in code example), then derive a new parameter type, which contains virtuals that you can use to read what they want the parameter values to be.
//base parameter type - provides the 'anchor' for our generic constraint later,
//as well as a nice, strong-typed access to our param values.
public class StaticParameterBase
{
public abstract string ParameterString{ get; }
public abstract MyComplexType ParameterComplex { get; }
}
//note the use of the new() generic constraint so we know we can confidently create
//an instance of the type.
public class MyType<TParameter> where TParameter:StaticParameterBase, new()
{
//local copies of parameter values. Could also simply cache an instance of
//TParameter and wrap around that.
private static string ParameterString { get; set; }
private static MyComplexType ParameterComplex { get; set; }
static MyType()
{
var myParams = new TParameter();
ParameterString = myParams.ParameterString;
ParameterComplex = myParams.ParameterComplex;
}
}
//e.g, a parameter type could be like this:
public class MyCustomParameterType : StaticParameterBase
{
public override string ParameterString { get { return "Hello crazy world!"; } }
public override MyComplexType { get {
//or wherever this object would actually be obtained from.
return new MyComplexType() { /*initializers etc */ };
}
}
}
//you can also now derive from MyType<>, specialising for your desired parameter type
//so you can hide the generic bit in the future (there will be limits to this one's
//usefulness - especially if new constructors are added to MyType<>, as they will
//have to be mirrored on this type as well).
public class MyType2 : MyType<MyCustomParameterType> { }
//then you'd use the type like this:
public static void main()
{
var instance = new MyType<MyCustomParameterType>();
//or this:
var instance2 = new MyType2();
}
I did consider a solution that employs custom type attributes applies to a type parameter, however this is easily a better way. However, you'll now be using your class always with a generic parameter type (unless you can use the deriving+specialisation trick) - possibly too clumsy for your liking.
I'd also prefer this over the other solutions presented here as it doesn't require creating any workarounds for the static initialisation - you can still use .Net's guarantee of single-time initialisation.
A word of warning - should you be reviewing your structure?
All that said - remember, though, since you can only parameterise the static once (or in this case, each uniquely parameterised static generic) - I would be asking myself why not just pull the code that is getting the parameters to give to the static, and place it in the static constructor in the first place? That way you don't actually have to resort to strange patterns like this!
I assume you mean static members of a class? In that case, you can do this:
public class MyClass
{
public static int MyInt = 12;
public static MyOtherClass MyOther = new MyOtherClass();
}
Those static members are guaranteed to be instantiated before any class is instantiated.
If you need complex logic, do it in a static constructor:
public class MyClass
{
public static int MyInt;
public static MyOtherClass MyOther;
static MyClass()
{
MyInt = 12;
MyOther = new MyOtherClass();
}
}
Edit
Based on your edit, I'd say just assign the values to what they need to be before you instantiate the class, like so:
public class MyClass
{
public static int MyInt;
public static MyOtherClass MyOther;
}
// elsewhere in code, before you instantiate MyClass:
MyClass.MyInt = 12;
MyClass.MyOther = new MyOtherClass();
MyClass myClass = new MyClass();
That said, this method gives you no guarantee that MyInt and MyOther are set before MyClass is instantiated. It will work, but requires discipline before instantiating MyClass.
One alternative pattern you might follow looks like this:
public class MyClass
{
private static int MyInt;
private static MyOtherClass MyOther;
private static bool IsStaticInitialized = false;
public static InitializeStatic(int myInt, MyOtherClass other)
{
MyInt = myInt;
MyOther = other;
IsStaticInitialized = true;
}
public MyClass()
{
if(!IsStaticInitialized)
{
throw new InvalidOperationException("Static Not Initialized");
}
// other constructor logic here.
}
}
// elsewhere in your code:
MyClass.InitializeStatic(12, new MyOtherClass());
MyClass myClass = new MyClass();
// alternatiavely:
MyClass myClass = new MyClass(); // runtime exception.
In Java I can write:
public class Foo {
public static Foo DEFAULT_FOO;
static {
DEFAULT_FOO = new Foo();
// initialize
DEFAULT_FOO.init();
}
public Foo() {
}
void init() {
// initialize
}
}
How can I get the same functionailty in C# (where static members are initialized before use)? And, if this is a bad thing to try to do, what is a better approach?
you use a static constructor, like this:
public class Foo
{
static Foo()
{
// inits
}
}
Here's more info.
Bottom line: it's a paramaterless constructor with the static keyword attached to it. Works just like the static block in Java.
Edit: One more thing to mention. If you just want to construct something statically, you can statically initialize a variable without the need for the static constructor. For example:
public class Foo
{
public static Bar StaticBar = new Bar();
}
Keep in mind that you'll need a static constructor if you want to call any methods on Bar during static initialization, so your example that calls Foo.Init() still needs a static constructor. I'm just sayin' you're not limited, is all. :)
Static is still the keyword in C#:
public class Foo {
public static Foo DefaultFoo;
static Foo {
DefaultFoo = new Foo();
// initialize
DefaultFoo.init();
}
public Foo() {
}
void init() {
// initialize
}
}