An object can outlive another ...What does it mean? - c#

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
}
}

Related

C# inheritance and interface implementation question: why is the output a zero? [duplicate]

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()
;

Sharing data between several instances

I have a class A and a class B that both need to work with a class C.
I want class A and B to work on the same instance of C in a way that changes made in A to C will affect the C object used by B.
The only way I see to implement this is by using the observer pattern, but I am curious to know if there are any simple solution to this problem.
Assuming declarations similar to following and setting sharedC in constructors:
class C{}
class A { private C sharedC; }
class B { private C sharedC; }
You'd use single instance of C and pass to instances of A and B that need shared copy.
var c = new C();
var a = new A(c);
var b = new B(c);
One of the simplest ways (assuming C is a class, not a struct)

Stack overflow exception, unable to find reason

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.

Accessing inherited private base class member...through derived class object...created in base class member

I can't wrap my head around why m() in class a can access x and y through the b class and b class object if x and y are private. I know that when b inherits from a, b receives private members from a even though they can't be used by b. But what is strange to me is that b members can't use x and y, and classes other than a can't get at the variables through b class and b class object, yet m() can access x and y through the b class and b class object.
Can someone explain this to me using a general rule that I missed or maybe an explanation about how the compiler does this 'giving' of base members to derived classes?
class a
{
private int x;
private static int y;
static void m()
{
b bobj = new b();
int mm = bobj.x;
int rr = b.y;
}
void n()
{
b bobj = new b();
int mm = bobj.x;
int rr = b.y;
}
}
class b : a
{
private int u;
private static int v;
static void o()
{
}
void p()
{
}
}
I can't wrap my head around why m() in class a can access x and y through the b class and b class object if x and y are private
Code within a class declaration can access any private members declared by that class - it's as simple as that. So code within a can't access private variables declared in b, but it can access private variables declared in a via an instance of a which also happens to be an instance of b.
Note that this line:
int rr = b.y;
is effectively converted to
int rr = a.y;
y is only declared by a - if it were really declared by b, it wouldn't be accessible.
See section 3.5 of the C# 4 language specification for more details.
This is a rule inherited from the C++ language.
private and protected operate on classes, not objects. Therefore, for example, if you have a Bank object, its members can access any other Bank's private data although it may seem counterintuitive or dangerous.
Because C++ extensively used pointer arithmetic and unlimited typecasts, there was no way to reliably protect data inside a process before any code executing in the same process.
If you, however, only need object level protection from accidental access, this can be helped by defining an interface and only passing interfaces between banks. While a Bank object still can do the following:
void TransferMoneyFrom(IBank otherBank, decimal theirAccountNumber,
decimal receivingAccountNumber, int amount)
{
((Bank)otherBank).PrivateProperty = whatever;
}
...it is less likely to happen unintentionally because explicit type casting or use of reflection are needed.
(Note that C# typically makes it easier to intentionally access a private member of some other class whose source code you do not have (by name, using reflection). If this is perceived as a disadvantage by the vendor of that type, they can use an obfuscator to make this more difficult. This still does not protect the obfuscated objects against other instances of itself in any way.)

How do I create a new object from an instance of its base class?

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 ...

Categories