Sharing data between several instances - c#

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)

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

C# Let multiple class share the same instance of another class

Is there any way to let multiple class share the same instance of another class?
So in my c# program i've got three class Gamelogic(A), FPSController(B), and SpawnPlayer(C).
In my case class B and C would use and alter some variables in A, in order to use the variables i'm currently instantiating A in two different classes and then use dot notation to access the variable from the instance of A, but the problem is that after A instantiated in different classes, the change in instance.variable does not share between B and C class at all.
Would static type be a good way of solving this? Or writing a main would be better.
Any suggestions would be appreciated.
There are a few ways. Here is one:
One way would be dependency injection.
You can pass the instance of A along to the constructors of B and C (or to a setter/property of B and C):
A a = new A();
B b = new B(a);
C c = new C(a);
But this doesn't allow you to change the A reference in both objects easily, which seems to be your problem.
One way to easily change the reference, is to wrap the reference in another object somehow.
A nice way to do this could be to create a Context object and pass that context object along to B and C instead of passing A. The context object plays the role as our wrapper. A context object becomes more useful if multiple variables needs to be shared between them (the shared/global state) - see the "Context pattern". Example:
public class Context {
public A a;
public ...other state you want to share...;
public Context(A a) { this.a = a; ... }
}
...
A a = new A();
Context context = new Context(a,...);
B b = new B(context);
C c = new C(context);
Depending on your situation, a static variable might be fine, however. (Or a singleton)
(In some cases passing the A-instance along to the methods of B and C, rather than to their constructor, might be better - then they also always get the current version of a (and might be more thread-safe))
It sounds like you only need to have one instance of each class and pass the data between them. There are several ways to achieve this.
Static classes are one way to go then you'd simply access/set Gamelogic.Property in each of FPSController and SpawnPlayer.
Another way would be to pass the instance of Gamelogic to FPSController and SpawnPlayer when they are created.
However, both of these couple your classes together in ways that might make future changes hard.
A third way would be to make all three classes independent and use events to change values of variables and notify the other classes of changes to these variables. This, however, would probably introduce some lag into your game as there's no guarantee that events are processes in the order you expect.
I can think of two ways, either implement the Singleton pattern for the given classes, which would ensure that only one instance exist at any given time and you can freely use it where ever, will thus achieve your purpose. Check the link by Jon skeet.
If Singleton is not an option then, create a factory, where you pass a key and for given key ensure that only same object is returned, as you can internally store the object in a Dictionary, which would always return same object and you can still create multiple object unlike Singleton
show, this my code.
public interface IMyInterface
{
void SetData(String Data);
}
public partial class Form1 : Form, IMyInterface
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Form2 frm = new Form2(this as IMyInterface);
frm.Show();
}
public void SetData(String Data)
{
textBox1.Text = Data;
}
}
public partial class Form2 : Form
{
private IMyInterface frm = null;
public Form2(IMyInterface frm)
{
InitializeComponent();
this.frm = frm;
}
private void button1_Click(object sender, EventArgs e)
{
frm.SetData(textBox1.Text);
}
}

How to get to a data object of class A from Class B (not from the main class)

Let's say I have 3 classes:
Main class, class A, class B
and let's also say that class B has a method which needs data from class A. (the data is actually a dataview object).
objects instances of class A and class B are created in the main class regardless of the above (for them to be created in general)
what would be the best way to reach the dataview object of class A from class B?
Should I make the dataview object internal? should I make it static? should I make it internal static?
I've learned to create properties in cases like these and just "get" the object, but since it's the main form (and not Class B) which creates an object of Class A, I can't reach that property from class B.
Edit, here is a demo code:
Class Main
{
A a = new A();
B b = new B();
a.doingAClassStuff(); //Not possible unless Class A is set to public or the method is set to internal (classes are internal by default)
b.doingBClassStuff(); //Likewise
//need to get the dv object here.
//dv.rows[1].foo = bar;
}
Here above in the main class I need to get the dv object from Class B.
//each class exist in a different class file (.cs file) inside the project
Class A
{
doingAClassStuff()
{
MessageBox.Show("Hello From Class A!");
}
//here access to the dv object is also needed.
//dv.rows[5].foo = something;
}
Class A also needs to get the dv object of Class B!
//in another file as well
Class B
{
DataView dv = new Dataview(datatable1)
doingBClassStuff()
{
MessageBox.Show("Hello From Class B!");
}
}
My notes:
Making "dv" only "Internal" will not make it visible.
Making "dv" "Internal Static" will make it visible and I can work with that but I am not sure "static" has no Cons, I am not creating more than 1 instance of each class (if it matters).
I tried setting properties with "get" and get it but since the properties are public and I couldn't set them to "internal" are they public to outside of the assembly as well?
Many Thanks!
Without any additional information in regards to your requirements and restrictions, this is how I would handle it.
If you need Class A for a Class B to operate properly, you should probably provide Class B with a Class A member and either initialize it in the constructor for Class B or provide a method to set the member.
Class A should then expose through its public interface what Class B needs in a manner that makes sense for the class. i.e. don't just make the DataView public.
public class A
{
private B _b;
public A(B b)
{
_b = b;
}
void UseData()
{
_b.GetData();
}
}
Public class B
{
public DataView GetData();
}
elsewhere
B b = new B();
A a = new A(b);
what would be the best way to reach the dataview object of class A from class B?
Some options:
Pass an instance of A to a method of an instance of B
Add a property to B of type A (if the instance would be used for multiple operations
Should I make the dataview object internal? should I make it static? should I make it internal static?
Make it internal if you want it accessible to all types within the same assembly but not outside of the assembly (basically private to the assembly
Make it public if you want it available to all types inside and outside the assembly
Make it static if the data would apply to all instances of A
I can't add a comment yet but this seems similar to the following post which asks for an equivalent to friend. The top answer says to use InternalsVisibleTo to achieve somewhat similar functionality.
What is the C# equivalent of friend?

An object can outlive another ...What does it mean?

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

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