i have piece of code
public class A
{
public A()
{
Console.WriteLine("A");
}
B b = new B("From A");
}
public class B : A
{
public B()
{
Console.WriteLine("B");
}
public B(string str) //Getting exception here
{
Console.WriteLine("In B " + str);
}
}
public class C : A
{
B b = new B("From C");
public C()
{
Console.WriteLine("C");
}
}
class Program
{
static void Main(string[] args)
{
new C();
Console.ReadKey();
}
}
Here, i know that all properties are initialized first before base constructor called, but i am unable to find why i am getting Stackoverflow exception. Any Help ?? Thanks
Because B inherits from A, it inherits the
B b = new B("From A");
field. So whenever you create a B object it creates another B object, in an infinite recursive chain.
So in the actual Program you have, you create a C object. This then constructs a B object using the overload that takes a string ("From C"). You then get an exception on that constructor, because it then recursively creates infinite B objects.
Recursive infinite loop:
Every time you create a B, you create a new A (through inheritance).
Every time you create an A, you create a new B (through variable b).
Since B inherits from A
//public class B : A
And when you create object of B in class A,It goes in recursive infinite loop.
The problem above is due to cyclic instantiation.
Here our thinking of instantiation causes these kind of issues:
Here when we instantiate C we just do not get object of class C but, it in fact is the combination of C+B+A.
These kind of problems can be easily identified by drawing an object diagram with Arrows from instantiating object to instanted object.
Related
I have simple three classes:
class A
{
public virtual void Write()
{
Console.Write("A");
}
}
class B:A
{
public override void Write()
{
Console.Write("B");
}
}
class C : B
{
public new void Write()
{
Console.Write("C");
}
}
And I am creating objects and calling their methods:
A a = new A();
a.Write();
A b = new C();
b.Write();
C c = new C();
c.Write();
And output will be: ABC
What I cannot understand is why these code produces B?:
A b = new C();
b.Write();
I thought that it should be C. However, I tested many times, and it is always B.
I understand that A b = new C() creates new object type of C. So output should be C. Or it is special behavior to call overridden method when we use it without casting?
Why does it happen? As we have not used any reference to B class.
It would work if you'd use ((C)b).Write();
With the new keyword you're not overriding the Write method for C but rather creating a new method only defined for C. So for your C you actually have 2 methods with a method name Write.
A c = new C();
c.Write(); //Output "B", you're calling the overridden method
((C)c).Write(); //Output "C", you're calling the method defined on C
//or
(c as C).Write();
The same happens when you would define c as C:
C c = new C();
c.Write(); //Output "C"
((A)c).Write(); //Output "B"
In the first example you're calling the new method defined on C. In the second line you are calling the Write method from A, which is overridden by B, hence the output "B".
Edit: (some more explanation)
Variable c is of type A, so that's what your compiler knows "c is an instance of A", it is not known that it is actually of a more derived type. When you call the method Write on it, it will invoke the method defined on A (which is overriden by B). Your base class A has no knowledge of your new method defined on C (that's what new does, create a new method), so unless you cast it to C to let the compiler know about the actual, derived type of c, the method of your base class will be called.
I now its really late and does not answer the question, but i needed that behavior and just in case some else need it i'll share it.
To get that beheavior you need to use interfaces, for example
interface Writer{
void write;
}
class A : Writer
{
void Writer.Write()
{
Console.Write("A");
}
}
And the same for the others. As you can see, you have to implement it explicity as well as call it explicity.
A c = new C();
((Writer) c).write()
;
I have simple three classes:
class A
{
public virtual void Write()
{
Console.Write("A");
}
}
class B:A
{
public override void Write()
{
Console.Write("B");
}
}
class C : B
{
public new void Write()
{
Console.Write("C");
}
}
And I am creating objects and calling their methods:
A a = new A();
a.Write();
A b = new C();
b.Write();
C c = new C();
c.Write();
And output will be: ABC
What I cannot understand is why these code produces B?:
A b = new C();
b.Write();
I thought that it should be C. However, I tested many times, and it is always B.
I understand that A b = new C() creates new object type of C. So output should be C. Or it is special behavior to call overridden method when we use it without casting?
Why does it happen? As we have not used any reference to B class.
It would work if you'd use ((C)b).Write();
With the new keyword you're not overriding the Write method for C but rather creating a new method only defined for C. So for your C you actually have 2 methods with a method name Write.
A c = new C();
c.Write(); //Output "B", you're calling the overridden method
((C)c).Write(); //Output "C", you're calling the method defined on C
//or
(c as C).Write();
The same happens when you would define c as C:
C c = new C();
c.Write(); //Output "C"
((A)c).Write(); //Output "B"
In the first example you're calling the new method defined on C. In the second line you are calling the Write method from A, which is overridden by B, hence the output "B".
Edit: (some more explanation)
Variable c is of type A, so that's what your compiler knows "c is an instance of A", it is not known that it is actually of a more derived type. When you call the method Write on it, it will invoke the method defined on A (which is overriden by B). Your base class A has no knowledge of your new method defined on C (that's what new does, create a new method), so unless you cast it to C to let the compiler know about the actual, derived type of c, the method of your base class will be called.
I now its really late and does not answer the question, but i needed that behavior and just in case some else need it i'll share it.
To get that beheavior you need to use interfaces, for example
interface Writer{
void write;
}
class A : Writer
{
void Writer.Write()
{
Console.Write("A");
}
}
And the same for the others. As you can see, you have to implement it explicity as well as call it explicity.
A c = new C();
((Writer) c).write()
;
I have the below code and I have only two simple questions which are normal to expect in the behavior of the program below, which I am not seeing unfortunately:
Static constructor in any class should be the first one to be hit soon after static fields being hit. Then only instance constructor. But what I am seeing is, the debug first goes to the public constructor. Sad thing. Why?
Although: the output of the program is:
This is Staticcc...
1
...Which is correct.
I kept a break point in the Static constructor start, but when I debug it only shows break point in the end brace of static constructor. Why?
Sample code:
public sealed class B : A, C
{
public int? m = 0;
public B()
{
m = 1;
}
private B(int a, int b)
{
m = 2;
}
protected B(int x, int y, int z)
{
m = 3;
}
static B()
{
Console.WriteLine("THis is staticcc");
}
public static B b = new B();
public static B BC
{
get
{
return b;
}
}
static void Main()
{
Console.WriteLine(B.BC.m);
Console.ReadKey();
}
}
public interface C
{
}
public class A
{
//private A()
//{
//}
}
This is the problem:
public static B b = new B();
Static field initializers are executed before the static constructor is executed. From the C# spec section 10.5.5.1:
If a static constructor (10.12) exists in the class, execution of the static field initializers occurs immediately prior to executing that static constructor.
Your static field initializer calls your instance constructor, therefore the instance constructor is the first thing to execute.
Although: the output of the program is This is Staticcc... then 1...Which is correct.
Yes, because all of the initialization happens as part of evaluating B.BC.m in Main.
If you add Console.WriteLine("Instance Constructor"); into your constructor, you'll see:
Instance Constructor
THis is staticcc
1
If that doesn't help, think of Main as being this:
int tmp = B.BC.m; // This prints initialization bits
Console.WriteLine(tmp); // This prints 1
That is because this line is ran before the static constructor:
public static B b = new B();
Your first line in the static constructor (the part you don't see, but is actually there) is actually calling the constructor of B. That is the reason you don't see the static constructor hit first.
If you would write it like this, you would see the static constructor hit first:
static B()
{
Console.WriteLine("THis is staticcc");
b = new B();
}
public static B b;
I am studying design patterns.
In the UML description aggregation its defined so : A has B , and B can outlive A.
Element to describe that is :
A<>------B (where the funny arrows, should be a diamond)
I simply do not understand the concept of "OUTLIVE" even if I understand that B type is in A under the form of a field (property...etc).
What do they mean with this "outlive" ?? In which case B can outlive A ?
It means that B is/could be referenced from outside A in some way.
It's easier to get in contrast with Composition, where B is solely 'owned' by A and then when A becomes unreachable, B automatically becomes garbage too.
So lifetime is used here to define visibility/scope. A little backward reasoning.
Consider the following code. A requires a B to instantiate, but destroying A does not destroy B.
When class C creates a new A, it gives it a reference to the B it already has. Now, even if A is destroyed, goes out of scope, etc. B is still 'alive.'
class A
{
private B b;
public A(B bType)
{
this.b = bType;
}
}
class B
{
}
class C
{
private B b = new B();
private A a;
public C()
{
a = new A(b);
a = null; // b is still alive
}
}
I have a base class, A, which has a method that returns an instance of itself:
class A
{
protected DateTime P { get; private set; }
protected A()
{
P = DateTime.Now;
}
protected A GetOneA()
{
return new A();
}
}
I need to create instance of child class B based on A object.
class B : A
{
private B(A a)
{
//help
}
public B GetOneB()
{
A a = A.GetOneA();
return new B(a);
}
}
Is it possible?
Yes it is possible. First create a "copy" constructor and pass a class instance of A. Inside this constructor you will need to copy all necessary attributes.
class A
{
protected DateTime P { get; private set; }
protected A(A copy){
//copy all properties
this.P = A.P;
}
protected A()
{
P = DateTime.Now;
}
protected A GetOneA()
{
return new A();
}
}
Then just call the super classes copy constructor.
class B : A
{
//help
private B(A a) : base(a)
{
}
public B GetOneB()
{
A a = A.GetOneA();
return new B(a);
}
}
Let me know if this is not what you are looking for.
Further reading on copy constructors: http://msdn.microsoft.com/en-us/library/ms173116.aspx
You made the constructor for A protected. B already contains an A because it is-an A. When the constructor for B is called, it will implicitly call the default constructor for A. What your GetOneB method is doing is calling GetOneA, which allocates an A, followed by allocating a B that is copy-constructed with A a as the parameter.
There's an issue of separation of concerns. There's initialization and there's allocation. If a B is-an A, and As can only be allocated a certain way, then B can not allocate only its A part a certain way and its B part another way. The whole B must be allocated in one manner, but the initialization of it can be done otherwise.
If A must be allocated in a manner different than the rest of B, then you must use containment and create a has-a relationship.
EDIT: We're talking C#, so most of that is irrelevant, because if you're working in C# you're probably not manually managing memory allocation. In any case, you don't need to call GetOneA, because B is-an A and A's constructor is called when B is constructed.
It is not technically possile no. That is, if I understand your goal to be to set an instance of some class to have an independent "parent" instance. It's just quite logically wrong I suppose.
You'd do better explaning what you want to do. Perhaps you may just like to copy the properties of the object into your own; in that case it's quite straight foward ...