Reputation: 21157
Ran across a very interesting problem at work yesterday.
I have 2 different classes named Foo and Bar. Each sitting in their own C# library project (separate dlls).
Bar contains a virtual method:
public class Bar
{
public virtual void DoSomething();
}
Foo uses an instance of Bar in its constructor to set an internal property:
public Foo (Bar myBar)
{
m_Bar = myBar;
}
Obviously, Foo has a reference to Bar's project.
Now, I have 5 other classes each of which also sits in its own project/dll. We'll call them A, B, C, D, and E. A-E are all subclassed from class Bar and each of them contain their own overridden implementation of DoSomething(). Because they are subclassed from Bar, any of them are valid as parameters for Foo's constructor.
A-E each maintain an inner collection of Foo instances. For example I would do something like this inside of Class A:
myFooCollection.Add(new Foo(this));
For this reason classes A-E all require a reference to Foo's project/dll.
Now, switching back to Foo for a moment lets say after setting the Bar property in the constructor I need to call the DoSomething() method of that Bar:
public class Foo (Bar myBar)
{
m_Bar = myBar;
m_Bar.DoSomething();
}
Bear in mind for example that Class A was used as the Bar parameter for the constructor. My call to DoSomething() needs to execute A's implementation of that method. However, since the constructor argument is of the parent class Bar and Foo has no knowledge of class A-E (I can't give it a reference without causing circular dependency) it will call the virtual method in the parent class Bar. The natural solution would be to downcast to the child class before making the call:
(A)m_Bar.DoSomething();
But this is out of the question as well since once again, Foo has no knowledge of this set of child classes. So here is my dilemma. The overall project structure cannot change because obviously the system is much bigger and more complex than what I've presented here. But my requirements are still the same. Foo needs to be able to reach the child implementation of DoSomething() in order to function properly. Any thoughts on how to solve this? If any clarification is required in better understanding the problem let me know and I will try and elaborate further.
Upvotes: 0
Views: 463
Reputation: 112492
You are not allowed to have static circular references of projects; however, you can have dynamic circular references of instances. If you call m_Bar.DoSomething();
then, because of polymorphy, the right implementataion will be called automatically. If m_Bar
is a Bar
then Bar
's implementation will be called. If m_Bar
is a A
then A
's implementation will be called. Neither Bar
nor Foo
need to know the existing of the classes A
through E
.
UPDATE: (see comments below)
public class A : Bar
{
public override void DoSomething()
{
Console.WriteLine("I am an 'A'");
}
}
Upvotes: 3