make a variable last for a call stack - c#

I have a class that contains some fields. I need to compare instances of this class by value, so I defined GetHashCode and Equals accordingly. Because the class allows circular references, I need a mechanism to avoid infinite recursion (for a more detailed explanation see Value-equals and circular references: how to resolve infinite recursion?). I solved this problem by modifying my Equals method so that it keeps track of the comparisons done before:
class Foo
{
public string Name { get; set; }
public Foo Reference { get; set; }
public override int GetHashCode() { return Name.GetHashCode(); }
static HashSet<(Foo,Foo)> checkedPairs
= new HashSet<(Foo,Foo)>(ValuePairRefEqualityComparer<Foo>.Instance);
// using an equality comparer that compares corresponding items for reference;
// implementation here: https://stackoverflow.com/a/46589154/5333340
public override bool Equals(object obj)
{
Foo other = obj as Foo;
if (other == null)
return false;
if !(Name.Equals(other.Name))
return false;
if (checkedPairs.Contains((this,other)) || checkedPairs.Contains((other,this)))
return true;
checkedPairs.Add((this,other));
bool refsEqual = Reference.Equals(other.Reference);
checkedPairs.Clear();
return refsEqual;
}
}
Imagine the following code in the main method:
Foo foo1 = new Foo { Name = "foo" };
Foo foo2 = new Foo { Name = "foo" };
foo1.Reference = foo2;
foo2.Reference = foo1;
bool foo_equals_bar = foo1.Equals(foo2);
Console.WriteLine("foo_equals_bar = " + foo_equals_bar);
foo1.Equals(foo2) will store (foo1,foo2) in checkedPairs before it calls foo2.Equals(foo1). Inside foo2.Equals(foo1) it will be noticed that checkedPairs contains (foo1,foo2), and true will be returned. This result is transferred to the equal variable inside the call of foo1.Equals(foo2), then checkedPairs is cleared, and true is finally returned to the main method.
(Without utilizing checkedPairs inside Equals, there would be an infinite recursion jumping between foo1.Equals(foo2) and foo2.Equals(foo1).)
This works allright in my single-threaded, non-concurrent sandbox environment. However, I am only using a static field for checkedPairs because I don't know any other way to transfer the already collected items from one call of Equals to the next inside a call stack.
But with this approach I cannot use a multi-threaded or concurrent environment, where several Equals checks might run in parallel or in a mixed-up order (e.g. due to passing Equals as a delegate and invoking it later on instead of immediately).
Questions:
Will using a thread-static variable work? I am afraid not, because I can imagine that different Equals calls from the same call stack could still be executed on different threads (but I don't know).
Is there a way to make checkedPairs "call stack static"? So that each call stack gets its own copy of checkedPairs? Then for each new call stack, a new (empty) checkedPairs would be created, filled during recursion, and garbage collected after the recursion ends.

Thanks jdweng to point me to an easy solution that works for the particular code stated in the question:
Remove the checkedPairs field from the Foo class and replace the Equals method by this code:
public override bool Equals(object obj)
{
return MyEquals(obj, new HashSet<(Foo,Foo)>(ValuePairRefEqualityComparer<Foo>.Instance));
}
private bool MyEquals(object obj, HashSet<(Foo,Foo)> checkedPairs)
{
Foo other = obj as Foo;
if (other == null)
return false;
if (!Name.Equals(other.Name))
return false;
if (checkedPairs.Contains((this,other)) || checkedPairs.Contains((other,this)))
return true;
checkedPairs.Add((this,other));
return Reference.MyEquals(other.Reference, checkedItems);
}
However, this approach is not going to work in general. Take for example the classes from this question: Value-equals and circular references: how to resolve infinite recursion?, and imagine I defined MyEquals analogously there for both Club and Person. Since MyEquals cannot be called from outside the class (I want it private), there will still be infinite recursion. E.g. when Person.MyEquals is called, it will call FavouriteInstitution.Equals inside, but it should redirect to FavouriteInstitution.MyEquals somehow(with a possibly already filled checkedPairs!). Also, Members.SetEquals(other.Members) will redirect to Person.Equals instead of Person.MyEquals.

Related

Is it meaningless to pass Dictionary<TKey,TValue> by ref? [duplicate]

If I am passing an object to a method, why should I use the ref keyword? Isn't this the default behaviour anyway?
For example:
class Program
{
static void Main(string[] args)
{
TestRef t = new TestRef();
t.Something = "Foo";
DoSomething(t);
Console.WriteLine(t.Something);
}
static public void DoSomething(TestRef t)
{
t.Something = "Bar";
}
}
public class TestRef
{
public string Something { get; set; }
}
The output is "Bar" which means that the object was passed as a reference.
Pass a ref if you want to change what the object is:
TestRef t = new TestRef();
t.Something = "Foo";
DoSomething(ref t);
void DoSomething(ref TestRef t)
{
t = new TestRef();
t.Something = "Not just a changed t, but a completely different TestRef object";
}
After calling DoSomething, t does not refer to the original new TestRef, but refers to a completely different object.
This may be useful too if you want to change the value of an immutable object, e.g. a string. You cannot change the value of a string once it has been created. But by using a ref, you could create a function that changes the string for another one that has a different value.
It is not a good idea to use ref unless it is needed. Using ref gives the method freedom to change the argument for something else, callers of the method will need to be coded to ensure they handle this possibility.
Also, when the parameter type is an object, then object variables always act as references to the object. This means that when the ref keyword is used you've got a reference to a reference. This allows you to do things as described in the example given above. But, when the parameter type is a primitive value (e.g. int), then if this parameter is assigned to within the method, the value of the argument that was passed in will be changed after the method returns:
int x = 1;
Change(ref x);
Debug.Assert(x == 5);
WillNotChange(x);
Debug.Assert(x == 5); // Note: x doesn't become 10
void Change(ref int x)
{
x = 5;
}
void WillNotChange(int x)
{
x = 10;
}
You need to distinguish between "passing a reference by value", and "passing a parameter/argument by reference".
I've written a reasonably long article on the subject to avoid having to write carefully each time this comes up on newsgroups
In .NET when you pass any parameter to a method, a copy is created. In value types means that any modification you make to the value is at the method scope, and is lost when you exit the method.
When passing a Reference Type, a copy is also made, but it is a copy of a reference, i.e. now you have TWO references in memory to the same object. So, if you use the reference to modify the object, it gets modified. But if you modify the reference itself - we must remember it is a copy - then any changes are also lost upon exiting the method.
As people have said before, an assignment is a modification of the reference, thus is lost:
public void Method1(object obj) {
obj = new Object();
}
public void Method2(object obj) {
obj = _privateObject;
}
The methods above does not modifies the original object.
A little modification of your example
using System;
class Program
{
static void Main(string[] args)
{
TestRef t = new TestRef();
t.Something = "Foo";
DoSomething(t);
Console.WriteLine(t.Something);
}
static public void DoSomething(TestRef t)
{
t = new TestRef();
t.Something = "Bar";
}
}
public class TestRef
{
private string s;
public string Something
{
get {return s;}
set { s = value; }
}
}
Since TestRef is a class (which are reference objects), you can change the contents inside t without passing it as a ref. However, if you pass t as a ref, TestRef can change what the original t refers to. i.e. make it point to a different object.
With ref you can write:
static public void DoSomething(ref TestRef t)
{
t = new TestRef();
}
And t will be changed after the method has completed.
Think of variables (e.g. foo) of reference types (e.g. List<T>) as holding object identifiers of the form "Object #24601". Suppose the statement foo = new List<int> {1,5,7,9}; causes foo to hold "Object #24601" (a list with four items). Then calling foo.Length will ask Object #24601 for its length, and it will respond 4, so foo.Length will equal 4.
If foo is passed to a method without using ref, that method might make changes to Object #24601. As a consequence of such changes, foo.Length might no longer equal 4. The method itself, however, will be unable to change foo, which will continue to hold "Object #24601".
Passing foo as a ref parameter will allow the called method to make changes not just to Object #24601, but also to foo itself. The method might create a new Object #8675309 and store a reference to that in foo. If it does so, foo would no longer hold "Object #24601", but instead "Object #8675309".
In practice, reference-type variables don't hold strings of the form "Object #8675309"; they don't even hold anything that can be meaningfully converted into a number. Even though each reference-type variable will hold some bit pattern, there is no fixed relationship between the bit patterns stored in such variables and the objects they identify. There is no way code could extract information from an object or a reference to it, and later determine whether another reference identified the same object, unless the code either held or knew of a reference that identified the original object.
This is like passing a pointer to a pointer in C. In .NET this will allow you to change what the original T refers to, personally though I think if you are doing that in .NET you have probably got a design issue!
By using the ref keyword with reference types you are effectively passing a reference to the reference. In many ways it's the same as using the out keyword but with the minor difference that there's no guarantee that the method will actually assign anything to the ref'ed parameter.
ref mimics (or behaves) as a global area just for two scopes:
Caller
Callee.
If you're passing a value, however, things are different. You can force a value to be passed by reference. This allows you to pass an integer to a method, for example, and have the method modify the integer on your behalf.

Does assigning an object to other creates a copy?

I tried with the below code, I got the output as 1000. I heard assigning object must share the reference instead of copying the entire object memory. Here the result is different.Can anyone help.
public aaaaa ad = new aaaaa();
static void Main(string[] args)
{
Program p = new Program();
p.fun1();
p.fun2();
}
public void fun1()
{
using(smallclass s = new smallclass())
{
s.j = 1000;
ad.fun1(s);
}
}
public void fun2()
{
ad.fun2();
}
public class aaaaa
{
public smallclass h = new smallclass();
public void fun1(smallclass d)
{
h = d;
}
public void fun2()
{
Console.WriteLine(h.j);
}
}
public class smallclass:IDisposable
{
public int j = 9;
public void Dispose()
{
GC.SuppressFinalize(this);
}
}
Update:
I expect an object reference exception as the referenced memory is disposed in p.fun1();
Here is an simple example how assinging works
using System;
namespace ConsoleApplication1
{
internal class Program
{
private static smallclass objA = new smallclass();
private static smallclass objB = new smallclass();
private static void Main(string[] args)
{
showValues();
objA.value = 1000;
showValues();
objB = objA;
showValues();
objA.value = 1055;
showValues();
}
private static void showValues()
{
Console.WriteLine("objA.value: " + objA.value);
Console.WriteLine("objB.value: " + objB.value);
Console.ReadLine();
}
}
internal class smallclass : IDisposable
{
public int value = 0;
public void Dispose()
{
//Here you can remove eventHandlers
//or do some other stuff before the GC will play with it
}
}
}
Like you can see
first we create 2 objects objA and objB
than we show the values like expected they are both 0
after that we increase the value of objA to 1000
the value of objA a is 1000 and the value of objB remains at 0
NOW we assingning objA and objB
so the value of objB got also 1000
if we now change the value of objA to 1055
the value of objB get also changed
because objB is no more an separate object it now holds the same
reference like objA does
EDIT
And now i will show you how you get your Error based on your example
change your aaaaa class to:
public class aaaaa
{
public WeakReference<smallclass> h;
public void fun1(smallclass d)
{
h = new WeakReference<smallclass>(d);
}
public void fun2()
{
smallclass k;
if(h.TryGetTarget(out k))
Console.WriteLine(k.j);
else
Console.WriteLine("ERROR ERRROR ERROR");
}
}
and modify your static void Main(string[] args) to:
static void Main(string[] args)
{
Program p = new Program();
p.fun1();
GC.Collect();
p.fun2();
Console.Read();
}
Ok lets get through the changes
we are using the WeakReference<T> (you could also use WeakReference)
if the GC now comes across our object he can't find a StrongReference so can Collect it
now to the GC.Collect() YOU need to call it because it forced the GC to do his work (now at this moment)
and remember like i told you before IDisposable will get called from the GC before he destroys the object (AFAIK) so there is the place to put all the stuff that need to be done before the object will get destroyed
No, assingning is not a "new" statement, it copies.... a reference, it does not create a new object. For a class.
For a struct, it does so.
I suggest learning C# by reading the documentation or a book - those basics are normally handled to great detail in those.
You will not go far wrong if you think of every reference type variable, field, parameter, array slot, or other such storage location, has holding either "null", or "object #24601" [or some other number]. There are really only a handful things that can be done with references:
You may create a null reference
You may ask the system to create a new object and return a reference to it
You may copy one reference to another
You may check whether two references are equal to each other, or whether one is equal to null.
You may ask the system to perform some action upon the object identified by a reference
If myCar is a variable of some reference type, a statement like myCar.Color = CarColors.Blue won't affect the variable myCar at all. Instead, it will observe that myCar holds [e.g.] "Object #8675309", and then ask the system to access the Color property or field of object #8675309. Conversely, if otherCar happens to hold "object #90210", a statement of the form otherCar=myCar won't do anything with object #8675309, nor object #90210, but will instead replace the "90210" stored in otherCar with "8675309".
Objects are guaranteed to exist as long as any form of reference to them exists, but if there are two objects which, although referenced by each other, are not referenced by anything else in the universe, both objects may simultaneously cease to exist. This rule is absolute, but there are a couple of twists: code may request a WeakReference to an object; an object is guaranteed to exist as long as a weak reference to it exists, but if the system discovers that no strong references to an object exist, it will invalidate every WeakReference to it. Further, the system keeps a list of all objects that have would like to be notified if they are abandoned. If the system finds that this list holds the only reference to an object, it will move the object to a strongly-referenced list of objects whose Finalize method should run at the first convenient opportunity. When the object's Finalize method is run, the reference will be removed from that latter list. If no reference to the object has been stored anywhere in the mean time, the object will cease to exist.
I have replaced GC.SuppressFinalize with GC.Collect() in dispose function, however this is not freeing the memory.. and am receiving 1000 as a result.
I guess, as it holds other reference(the variable h), GC will not free the memory, even if we invoked it explicit.
So we can very well pass and assign the objects irrespective of the allocated(new) object going out of scope.
Please correct me If i am wrong.

Why would I ever want to do object.ReferenceEquals(null, this) in Equals override?

Consider the following code that I was reviewing:
public override bool Equals(object other)
{
return !object.ReferenceEquals(null, this)
&& (object.ReferenceEquals(this, other)
|| ((other is MyType) && this.InternalEquals((MyType)other)));
}
The first line in this code triggered my curiosity. Whenever this is null, the method should return false. Now I am pretty sure the programmer meant to write !object.ReferenceEquals(other, null), to shortcut situations with null, but he's insistent that this can be null. I'm insistent that it cannot (unless someone uses direct memory manipulation). Should we leave it in?
While I certainly wouldn't normally check this for nullity, it's possible, without any actual memory nastiness - just a bit of reflection:
using System;
public class Test
{
public void CheckThisForNullity()
{
Console.WriteLine("Is this null? {0}", this == null);
}
static void Main(string[] args)
{
var method = typeof(Test).GetMethod("CheckThisForNullity");
var openDelegate = (Action<Test>) Delegate.CreateDelegate(
typeof(Action<Test>), method);
openDelegate(null);
}
}
Alternatively, generate IL which uses call instead of callvirt to call an instance method on a null target. Entirely legit, just not something the C# compiler would normally do.
This has nothing to do with finalization, which is hairy in its own right but in different ways. It's possible for a finalizer to run while an instance method is executing if the CLR can prove that you're not going to use any fields in the instance (which I would strongly expect to include the this reference).
As for the code presented - nope, that looks like it's just a mistake. I would rewrite it as:
public override bool Equals(object other)
{
return Equals(other as MyType);
}
public bool Equals(MyType other)
{
if (ReferenceEquals(other, null))
{
return false;
}
// Now perform the equality check
}
... assuming that MyType is a class, not a struct. Note how I'm using another public method with the right parameter type - I'd implement IEquatable<MyType> at the same time.
C# doesn't normally allow methods to be called on null. I think that the programmer who wrote that is either coming from a C++ background (where I think methods can be called on null, as long as they don't access a data member of this) or writing defensively for special scenarios (such as invocation by reflection, as has already been said).

How to pass method as a parameter for another method

I need to examine in "parent" object is there an acceptable at a definite moment to call some method in the "child". For example, parent object (component) includes child objects (or component parts in other words) and parent is disposing now, so all (or particlar) child activities must be prohibited (i.e. starting new service threads, enqueueing new client requests, ...).
public class Parent
{
public bool IsMethodCallAcceptable(reference_to_method) {...}
}
public class Child
{
public int SomeMethod(int intArg, string stringArg)
{
if(!_parent.IsMethodCallAcceptable(reference_to_SomeMethod_with_actual_args))
throw new ...
...
}
private void AnotherMethod(string param = null) {...}
{
if(!_parent.IsMethodCallAcceptable(reference_to_AnotherMethod_with_actual_args))
throw new ...
...
}
private Guid ThirdMethod()
{
if(!_parent.IsMethodCallAcceptable(reference_to_ThirdMethod))
throw new ...
...
}
}
Is there any way to do it?
Note: I am answering your question, not your title. Others have answered the title.
Some objects have an isDisposed property, if your parent implements that and that is the only time you don't want to call methods, then yes. Otherwise no. If you control the source for the parent, you could add a property that does what you want.
If you don't control the source and you want to check more than isDisposed or the parent doesn't implement isDisposed, you might be able to check publicly exposed properties, but generally you should assume that if a method is exposed to the public, that it is acceptable to call it at any time. If you're calling private methods via reflection, then you're taking chances.
Edit in response to comment:
Given your description, delegates won't give you any additional capability that you can't do easier by adding properties and methods to the parent (if you don't control the source, they won't help at all). The best method for dealing with your described scenario (CAR.ENGINE.START when out of gas, is for the Start method to either throw an exception or return a value indicationg the result of the attempt to start the engine).
Use delegates?
http://msdn.microsoft.com/en-us/library/ms173171%28v=vs.80%29.aspx
The easiest way is to pass an URI instead of a reference:
"NS.Child.ThirdMethod" for example.
Otherwise, a delegate is what is the closest to a function reference. You can pass that if you want.
However, this method is not compliant with OOP conception rules: Base class should know nothing about its children classes.
It's better to use some kind of locking mechanism to tell the children that they can't have access to the resources.
use func Func<T, TResult>
link
If these methods are native to the child class, the parent can't know anything about them for sure. Rice's Theorem will cause you all kinds of problems, if you could even see the code. Same problem (but to a lesser degree) if they're native to the parent class and are being overridden in the child, since you can't really guarantee that the child class will be doing everything (and only those things) that the parent class does; in fact, you can all but guarantee it will do something different. (If it didn't, why override?)
If they're native to the parent class and not overridable in the child, then just check whether the object is in a valid state for doing such a thing and throw an exception if it isn't.
As far as the actual validity check, for your example you can have a method like bool IsDisposing(); for other cases, you might keep track of the state in some other way. A private method like CanDoThisThing() might help, for example. Having a method that takes a generic operation name (not an operation; we already established the infeasibility of that) seems kinda broken to me.
Thank you all again, the result in the first approach is listed below
public class Component
{
public ComponentPart SomeComponentPart1 { get; private set; }
public ComponentPart SomeComponentPart2 { get; private set; }
public Component()
{
SomeComponentPart1 = new ComponentPart(this);
SomeComponentPart2 = new ComponentPart(this);
}
public bool IsMethodCallAcceptable(MethodCallExpression method, object[] parameters)
{
// collect needed information about caller
var caller = (method.Object as ConstantExpression).Value;
var methodName = method.Method.Name;
var paramsArray = new Dictionary<string, object>();
for (int i = 0; i < method.Arguments.Count; i++)
paramsArray.Add((method.Arguments[i] as MemberExpression).Member.Name, parameters[i]);
// make corresponding decisions
if (caller == SomeComponentPart2)
if (methodName == "SomeMethod")
if ((int) paramsArray["intArg"] == 0 || (string) paramsArray["stringArg"] == "")
return false;
return true;
}
}
public class ComponentPart
{
private Component Owner { get; set; }
public ComponentPart(Component owner)
{
Owner = owner;
}
public int SomeMethod(int intArg, string stringArg)
{
// check if the method call with provided parameters is acceptable
Expression<Func<int, string, int>> expr = (i, s) => SomeMethod(intArg, stringArg);
if (!Owner.IsMethodCallAcceptable(expr.Body as MethodCallExpression, new object[] { intArg, stringArg }))
throw new Exception();
// do some work
return stringArg.Length + intArg;
}
public void AnotherMethod(bool boolArg, Dictionary<Guid, DateTime> crazyArg, string stringArg, object objectArg)
{
// check if the method call with provided parameters is acceptable
Expression<Action<bool, Dictionary<Guid, DateTime>, string, object>> expr =
(b, times, arg3, arg4) => AnotherMethod(boolArg, crazyArg, stringArg, objectArg);
if (!Owner.IsMethodCallAcceptable(expr.Body as MethodCallExpression, new [] { boolArg, crazyArg, stringArg, objectArg }))
throw new Exception();
// do some work
var g = new Guid();
var d = DateTime.UtcNow;
}
}
This is variant how to check method calls, the same approach can be used in order to check properties values changes, while some ComponentPart' methods and properties can check some public Component.State property (via ComponentPart.Owner) instead of calling Component.IsMethodCallAcceptable or Component.IsPropertyChangeAcceptable.

What design pattern?

I have a class A maintaining a list of objects class B.
But each object of class B can be referenced in any object of class A.
Class B also maintains a list of objects of class A where it is being referenced.
The program can and will create (several) objects of both class A and B 'at will' and also delete them.
If I use C# I can add and delete objects from both classes with following code
public class A
{
private List<B>ListOfObjects_B;
public bool Add(B Object)
{
bool bAdd = false;
if ((Object != null) && (ListOfObjects_B.IndexOf(B) <0))
{
ListOfObjects_B.Add(Object);
Object.Add(this);
bAdded = true;
}
return bAdded;
}
public bool Delete(B Object)
{
bool bDeleted = ListOfObjects_B.Remove(Object);
if (bDeleted == true) Object.Delete(this);
return bDeleted;
}
}
public class B
{
private List<A>ListOfObjects_A;
public bool Add(A Object)
{
bool bAdd = false;
if ((Object != null) && (ListOfObjects_A.IndexOf(A) <0))
{
ListOfObjects_A.Add(Object);
Object.Add(this);
bAdded = true;
}
return bAdded;
}
public bool Delete(A Object)
{
bool bDeleted = ListOfObjects_A.Remove(Object);
if (bDeleted == true) Object.Delete(this);
return bDeleted;
}
}
This will work as because of removing/adding the object to the ListOfObjects the SECOND time (by recursion) the function will be called it will fail to delete/add thereby avoiding an infinite loop.
But I don't like this code even though A and B do not know 'much' about the other class and just call a Delete/Add function.
I suppose this kind of problem is general and a design pattern exists for handling it in such a way that recursion can be avoided and updating both lists will be 'just better'.
What design pattern should I use? I would appreciate if some code would be added as well.
You can simplify thing by moving the "object association concern" into a dedicated class. Here's what I have in mind.
Define a class called AssociationTable. This class will maintain a list of pairs where each pair holds a reference to an A object and a reference to a B object.
Each A object (and each B object) will hold a reference to the AssociationTable object.
A.Add(B) will be implemented as table.add(this, b);
B.Add(A) will be implemented as table.add(a, this);
Deletion will be implemented as table.delete(this, b) or table.delete(a, this)
class Pair {
A a; B b;
Pair(A a, B b) { this.a = a; this.b = b; }
// Also override Equals(), HashCode()
}
class AssociationTalbe {
Set<Pair> pairs = ...;
void add(A a, B b) { pairs.add(new Pair(a, b)); }
void remove(A a, B b) { pairs.remove(new Pair(a, b)); }
}
class A {
AssociationTable table;
public A(AssociationTable t) { table = t; }
void add(B b) { table.add(this, b); }
void remove(B b) { table.remove(this, b); }
}
Edit:
The problem with this design is garbage collection. the table will hold references to objects thereby supressing their collection. In Java you could use a WeakReference object to overcome this issue. I am pretty sure there's something similar in the .Net world
Also, the table could be a singleton. I don't like singletons too much. In here, a singleton will make the A-B association unique across your program. This may be something that is undesirable but it depends on your concrete needs.
Finally, (just to put things in context) this design works the same way as Many-to-Many relationships in relational data bases.
I recently wrote a class to handle a similar problem. It is actually a simpler scenario (parent/child relationship with the children referencing their parent), but you could probably adapt it for your needs. The main difference is that the Parent property in my implementation should be replaced by a collection of parents.
About the only thing I can think of is using a Mediator pattern so that A doesn't add itself to B. Here's an example:
public class Mediator {
public void Add(A List, B Object) {
if(list.Add(Object)) {
object.Add(List);
}
}
public void Delete(A List, B Object) {
if(List.Delete(Object)) {
Object.Delete(List);
}
}
}
After this you would remove the lines of code which read "Object.Add(this);" and "if (bDeleted == true) Object.Delete(this);" This also has the benefit of reducing how many times each method is called as before object A's methods were being called twice since object B was also calling those methods on object A.
EDIT: Upon further review, I realized you were already using an Observer design pattern in a way. Object A is the observer and object B is the observable. Object A maintains a list of objects its observing and object B maintains a list of objects observing it. The only thing is I don't see any additional functionality, although there probably is some. Basically, Object B will notify all Object A's observing it that it's changed and all of those Object A's will ask for the change. If this is what you're looking for, then all you need to do is remove the lines "Object.Add(this);" and "if(bDeleted == true) Object.Delete(this);" from the B code as it is unnecessary.

Categories

Resources