pass values between classes

  • Thread starter Thread starter liyang3
  • Start date Start date
L

liyang3

Hi,

I have Class A, B and C.

Class A has an instance of B. Class B has an instance of C. In the
instance of C, it generates some data that need to be passed back to
Class A. But Class C doesnot know anything about Class A.

I'm dealing with legacy code. What is the best way to implement it and
have the code change to existing classes such as A and B small? Any
ideas?

Thanks!
 
This seems trivial but here it is.
class classa
{
private classb b;
private int csvalue;
classa()
{
b=new classb();
this.dosomething();
}
public dosomething()
{
csvalue=b.c.myvalue;
}
}
class classb
{
private classc c;
classb()
{
c=new classc();
}
}
class classc
{
public int myvalue;
classc()
{
myvalue=5;
}
}
 
Note that circular references are allowed in C#. If an object is
unreachable it
is eligible for garbage collection even if there are circular
references. so if A
references C and C references A but the application no longer holds
references to A or C, A and C can still be garbage collected.

If C is not allowed to call A, or callback A when done, or in some way
notify A
that it is done, then you are left with polling. A.b.isDone B.c.isDone
-->
A.b.GetData() B.c.GetData().

Regards,
Jeff
Class A has an instance of B. Class B has an instance of C. In the
instance of C, it generates some data that need to be passed back to
Class A. But Class C doesnot know anything about Class A.

I'm dealing with legacy code.
 
This strikes me as a design problem that requires a larger knowledge of
your problem domain.

What are you trying to do? What are A, B, and C? When does the data
need to be passed back and what does that mean in domain terms?
 
Class A is a user-defined control: It's basically a window that
contains a panel and a paging navigator (with the back and forward
arrow buttons).

Class B is a class that instantiates class C to generate an array of
report objects.

Class C is a class that starts the invokes the printdocument.Print
object, and it takes care of printing each page of the report.

The graphics of each report page is passed back to Class A via the
generic event of OnEndPage of the print controller that takes
PageEventArgs as parameter, so the panel in Class A would show the
report page.

The original design works all fine until now I need to pass something
more than just what the PageEventArgs hold (graphics, bounds,
hasmorepages etc.). What I need to do is to pass an array of
information that contains the page number and the object of the report
back to Class A for future use. Since I can't use the same way of
passing the graphics back (the OnEndPage event), I need to come up with
some event on my own - Each time when a page is generated, my array
needs to be passed back to Class A. Please note that drawing each page
happens on worker thread while Class A is in the main thread.

I've got an idea of how to pass info from worker thread to main thread
- by using
MdiForm.BeginInvoke(new EventHandler(UpdatePageObjectReference),
pList);
in which pList is the array I need to pass over.

I defined the event handler "UpdatePageObjectReference" in Class A, but
at this point, in Class C, I don't hold an instance of Class A so it
won't recognize "UpdatePageObjectReference" event handler.

Please let me know about your thoughts.

Thanks,

Li
 
If you have control over the source code then you can define your own
custom delegate, your own OnEndPagePrintEventArgs, your own event
dispatcher and pass the custom delegate in the constructor chain. Class
C
fires the custom event after printing each page and Class A subscribes
to the
event. Sample code at:

http://www.geocities.com/jeff_louie/call_console.htm

Regards,
Jeff
 
Thanks a lot for the ideas and sample code! I tried another approach by
defining an interface that contains one method. Have class A inherit
from the interface and expose this interface part to C. (passed through
B to C). Finally when C is ready to update A, it calls the method. Then
in A, I call Invoke using MarshalEventDelegate to marshall the data
over to the main thread. This has so far worked fine.
 
Glad to hear you got it to work. Interfaces would be my natural choice
in Java
also. I am coming to understand that delegates and events allow the
framework designer to build in _potential_ support for notification. So
a
WinForms program has build in support for the Closing event, but I do
not
have to subscribe to this event initially. If I decide that I want to
trap the
closing of the window I just do.

this.Closing += new CancelEventHandler(this.Form1_Closing);

private void Form1_Closing(object sender,
System.ComponentModel.CancelEventArgs e)
{
    if (isDirtyDocument)
    {
        if (MessageBox.Show ("Really? Quit Without Saving?", 
                                            "Draw",
                                            MessageBoxButtons.YesNo, 
                                            MessageBoxIcon.Question)==
DialogResult.No)
        {
            // Cancel the Closing event from closing the form.
            e.Cancel = true;
        }
    }
}


Regards,
Jeff
I tried another approach by
defining an interface that contains one method.<
 
Back
Top