Can I call a constructor from same class method in C#?
Example:
class A
{
public A()
{
/* Do Something here */
}
public void methodA()
{
/* Need to call Constructor here */
}
}
The short answer is No :)
You cannot call constructors as simple methods except these special cases:
You create a new object: var x = new ObjType()
You call a constructor from another constructor of the same type:
class ObjType
{
private string _message;
// look at _this_ being called before the constructor body definition
public ObjType() :this("hello")
{}
private ObjType(string message)
{
_message = message;
}
}
You call a base type constructor from a constructor:
class BaseType
{
private string _message;
// NB: should not be private
protected BaseType(string message)
{
_message = message;
}
}
class ObjType : BaseType
{
// look at _base_ being called before the constructor body execution
public ObjType() :base("hello")
{}
}
UPD. Regarding the workaround with an initialization method proposed in another answer - yes, it's probably a good way. But it's a bit tricky because of the object consistency, which is the reason why constructors are even exist. Any object method is expected to receive the object (this) in a consistent (working) state. And you cannot guarantee it calling a method from a constructor. So any person editing that initialization method or calling constructor in future (probably you) could expect having this guarantee which greatly increases the risk of making mistake. The problem is amplified when you deal with inheritance.
Besides provided answer which answers the question, an easy away to fix your problem is to define an initialization method that is called from both the constructor and your method:
class A
{
private init()
{
// do initializations here
}
public A()
{
init();
}
public void methodA()
{
// reinitialize the object
init();
// other stuff may come here
}
}
Shortly put, you cannot call the constructor, but you don't have to :)
Related
today I saw a snipped that looked really horrible to me, but unfortunetly I cannot simply change it, so I wonder if I can bypass this somehow. I have a class with a constructor that has an output-parameter for success. But that looks really ugly to me. And now when deriving from this class I have to take this param with me- if I want to or not.
class ClassA {
ClassA(out bool success) {...}
}
class B: ClassA {
// call the constructor from ClassA but without the out-param
}
So I´d know if its good practise or if not how I can avoid declaring the out-param from ClassB.
While passing ref or out parameters to a constructor is ugly, there are some types where attempts to create a usable instance will have side-effects, and might fail after some of those side-effects have already occurred. If it is not possible to construct a valid object, the only ways via which the constructor can pass information to the caller are by storing it in a threadstatic field, encapsulating it within the thrown exception, storing or feeding it to a passed-in object or delegate, or writing it to a ref/out parameter. Of those, only the ref/out parameter makes obvious the existence of information with which the client code should be doing something.
The existence of ref or out parameters is often an indication that a constructor should be protected, and that outside code should go through a factory methods which ensure that if an exception is thrown the passed-out object will get used suitably. For a class to reasonably support inheritance, however, it must offer at least one constructor which is visible outside it. Having that constructor use an out or ref parameter may be the least evil way for a class to let a caller know what things will need cleaning up if construction fails.
You can do something like this:
class ClassA
{
protected ClassA(out bool success)
{
success = true;
}
}
class B : ClassA
{
[ThreadStatic]
static bool success; // static to use in base(out success) call
public bool Success
{
get;
private set;
}
public B()
: base(out success)
{
Success = success;
success = false; // reset value
}
}
It's ugly, but at least you get rid of the out parameter if so you want.
Well, the design of that class is broken anyway, so let's break it a bit more (NOTE! I do not recommend this approach!):
void Main()
{
}
public class ClassA
{
public ClassA(out bool success)
{
success = true;
}
}
public class B: ClassA
{
private static bool success;
// call the constructor from ClassA but without the out-param
public B()
: base(out success)
{
}
}
Other than that, the closest you can get is making a factory method:
public class B : ClassA
{
public static B Create()
{
bool success;
var result = new B(out success);
if (success)
return result;
// TODO: Dispose result?
throw new StupidProgrammerException();
}
}
If you really don't care about the value of the out parameter, in newer versions of C# you can declare an out variable inline and you can choose to do nothing with it:
class B : ClassA
{
B() : base(out bool ignore) { }
}
You can go further and use the special discard name _ to let the compiler know you won't use the variable. This way you don't even need to declare its type:
class B : ClassA
{
B() : base(out _) { }
}
I have a job interview tomorrow and I'm trying to answer this question:
There is a class named C and method m in this class, this class have also empty constructor:
Main ()
{
C c = new c();
}
Class C {
public c {
//empty constructor
}
public m {
//does something - doesnt mind
}
}
And what you have to do is to change the code so that in a creation of an instance class C, the method m would be called before the class constructor.
You have to do this without changing the main (edit only the class code).
Thanks in advance!
Like the other answers have said, you can make the method static. But then you need to explicitly call it. If you make a static class constructor, that will get called once automatically (you don't need to call it), the first time the class is referenced (like when you construct the first instance). You can't exactly control when it executes, but it will execute before the first instance is constructed. Based on the way they've worded the question (you can't change the Main method), I think static class constructor is the answer they're looking for.
http://msdn.microsoft.com/en-us/library/k9x6w0hc%28v=vs.80%29.aspx
Static constructors have the following properties:
A static constructor does not take access modifiers or have parameters.
A static constructor is called automatically to initialize the class before the first instance is created or any static members are
referenced.
A static constructor cannot be called directly.
The user has no control on when the static constructor is executed in the program.
Java doesn't have static class constructors, but they do have static initialization blocks..
static {
// code in here
}
To call a class's method before its constructor gets called you either have to turn this method into static so you don't need an instance of that class to call it, or (in C#) you can use FormatterServices.GetUninitializedObject Method to get an instance of your class without running the constructor (which of course may not be a wise thing to do).
In JAVA:
make method static and call your method in static block.
class C{
static{
m();
}
public C() {
System.out.println("Constructor Called..");
}
public static void m() {
System.out.println("m() is called.");
}
}
Main call
public static void main(String[] args) {
new C();
}
In both Java and C# you can use, base class constructors, static constructors (Edit: static initializer block in Java), and field initializers, to call code before the C class's constructor executes without modifying Main.
An example using a field initializer block in Java:
class C {
{ m(); }
public C() {
System.out.println("cons");
}
public void m() {
System.out.println("m");
}
}
This prints "m", then "cons". Note that m is called every time a C is constructed. A static initializer block would only be called once for the JVM.
Its basic OOP. You have to make a public static method and call it. That method can then call the constructor, or you can call the constructor directly from main.
Before you call the constructor, the object don't exist, therefore no instance methods exist, therefore nothing tied to the instance/object can be called. The only things that do exist before the constructor is called is the static methods.
Following way seems to achieve what is required. Without using static methods/variables
namespace FnCallBeforeConstructor
{
static void Main(string[] args)
{
MyClass s = new MyClass();
Console.ReadKey();
}
partial class MyClass: Master
{
public override void Func()
{
Console.WriteLine("I am a function");
}
public MyClass()
: base()
{
Console.WriteLine("I am a constructor");
}
}
class Master
{
public virtual void Func() { Console.WriteLine("Not called"); }
public Master()
{
Func();
}
}
}
Output is:
I am a function
I am a constructor
Here is the code:
class Class1
{
private Class2 object;
public Class1(Class2 obj) : this(obj.ToString())
{
this.object = obj;
}
}
More specifically, what does the : this part do.
The :this(obj.ToString) causes the constructor code for the constructor defined taking a string parameter to run first. Once it runs, then the constructor code (setting this.object = obj) is executed.
This is covered in MSDN's page on Constructors (the last example set).
Note that, in your code above, as written, this will cause a compiler error. You would also need to have a constructor like the following:
public Class1(string str) // Constructor taking a string, though it could be non-public
{
// Do something with str
}
With this constructor in place, it will get called, perform it's initialization steps, then the first constructor (which sets this.object) will run.
: this(obj.ToString()) calls overloaded version of constructor from same class.
It means that somewhere in this class you have another constructor which takes string as parameter and will be executed alongside current constructor.
class A
{
public A(Class2 obj): this(obj.ToString()) // execute A(string text)
{
// your code
}
public A(string text)
{
// your code
}
}
Class 1 will have another constructor that takes a string parameter.
It calls the constructor that matches that syntax. In your case, I'm assuming there's a constructor that takes a string argument somewhere:
public Class1(string s)
{
}
I'm trying to pass a delegate as a parameter in the ctor of a class like this
class Foo
{
protected delegate void CreateResource(object parameter);
protected Foo(CreateResource res)
{
}
public Foo(string resourceName)
: this(CreateStreamRes) // Compiler error
{
}
protected void CreateStreamRes(object o)
{
}
}
But I get the following compiler error in the commented line: "An object reference is required for the non-static field, method, or property 'CreateStreamRes(object)'".
However if I Add a variable inside the constructor like this
public Foo(string resourceName)
: this(CreateStreamRes) // Compiler error
{
CreateResource cr = CreateStreamRes; // OK
}
it compiles that line successfully.
It seems like the C# treats the constructor as a static method. Because if I add the static keyword to the CreateStreamRes(object o) method it compiles nice.
Can someone explain me why is this happening?
You cannot use a non-static method there, because the object hasn't been constructed yet! Just define CreateStreamRes as static and be done with it!
Now, I'm sure Eric Lippert can give you a proper explanation about why this is the case, but I think of it like this: Using the :this() syntax will get translated into calling that constructor first and then doing whatever is in the constructor body afterwards. So you can't really use instance methods on an object that doesn't exist yet, right?
You could factor out the portion body of the constructor and call that:
class Foo
{
protected delegate void CreateResource(object parameter);
protected Foo(CreateResource res)
{
Initialize(res);
}
protected void Initialize(CreateResource res)
{
}
public Foo(string resourceName)
{
Initialize(CreateStreamRes(res));
}
protected void CreateStreamRes(object o)
{
}
}
This works, because by the time you call Initialize, the object has been allocated. Inside the constructor you are free to use instance methods.
You cannot call instance method when calling the :this() keyword. That's because the instance of the class is not yet created. If you need to invoke some method there it must be static.
I have an object pool, and I need to call a delegate method OnFree(), whenever I call Free() on an object in the pool.
Free() is created externally and set on the object when the pool is created. OnFree differs from one object to another, and sometimes it is even null.
Objects in the pool inherit from the Poolable class.
class Poolable
{
public Action Free();
public Action OnFree();
}
Currently I create OnFree in the inheriting class by doing this:
class Light
{
public Light()
{
// Create method to be called when Free() is called on this light.
OnFree = () =>
{
DoStuffHere();
};
}
}
However, this will create a separate delegate for each light, which wastes a bunch of memory especially when there are tens of thousands of objects in the pool. Er, it does create a new delegate every time this constructor is called, right?
What is a good way to allow objects to create their own OnFree() delegate, so that there is only one delegate per object type, instead of one delegate per instance?
I can think of a way of course, but I'm hoping someone can think of a "good" way -- something that allows easy maintainability.
Edit: Can I make the OnFree() delegate static in the base class, so that it is static per inherited type somehow?
Edit: To clarify how Pool is used, and why Free() is a delegate, not a virtual method. Please let me know if you can think of a better way to do this.
public class Pool<T> where T : Poolable
{
private int _liveCount;
private T[] _pool;
[...]
public Pool(int capacity, Func<T> allocateFunction)
{
[...]
// Fill pool with initial items:
for (int i = 0; i < capacity; i++)
{
T item = _allocate();
item.Free = () => Free(item);
_pool[i] = item;
}
}
/// <summary>
/// Frees given object from this pool. Object is assumed to
/// be in this pool.
/// </summary>
public void Free(Poolable obj)
{
obj.OnFree();
_liveCount -= 1;
[...]
}
}
How about keeping it simple:
class Poolable
{
public virtual void Free() { }
public virtual void OnFree() { } // naming not according to BCL std
}
class Light : Poolable
{
public override void Free() { }
...
}
your example shows no need for delegates (over virtual methods)
proper encapsulation would require events instead of public delegates
looks like you are optimizing prematurely.
It actually depends on where DoStuffHere() is defined. If this is an instance method, there is an implicit capture of this onto a compiler-generated type; likewise anything else (not shown in your example) might be captured.
In most normal cases the extra overhead of a delegate instance is minimal. One workaround to avoid passing creating a delegate is to have a parameterised delegate (an Action<SomeStateType>, perhaps stored in a static field), and feed the state in as a separate parameter... but of course, then you are creating an object for the state! The slight advantage of doing a manual capture is that you are probably (it depends on the exact code sample) reducing it from 2 (or more) allocations (1 delegate, 1-or-more capture classes) to 1 allocation (your manual capture; the delegate being held on a static field).
One way of another, there is likely going to be something created. Personally, until your profiling shows it is a bottleneck, I think you should relax a bit - allocations are very fast, and most times the object will be collected in GEN-0, which is very efficient.
If you use a static generic class you get one "instance" per type - which is exactly what you were after. Hence, using such a class as the backstore for your type-specific delegates, and initialize them in the static constructor of each Poolable sub-class would solve your problem. See the sample code:
public class Poolable
{
public Action Free { get; set; }
public Action OnFree { get { return GetOnFree(); } }
protected virtual Action GetOnFree() { throw new NotImplementedException(); }
}
public static class PoolHelper<T> where T : Poolable
{
public static Action OnFree { get; set; }
}
public class Light : Poolable
{
static Light()
{
PoolHelper<Light>.OnFree = () =>
{
// Define 'OnFree' for the Light type here...
// and do so for all other other sub-classes of Poolable
};
}
protected override Action GetOnFree()
{
return PoolHelper<Light>.OnFree;
}
}