I have the following class :
public class MyFragment
{
/// members + methods
void proc();
}
public class MyProc
{
/// members + methods
}
public class MyClass
{
private MyProc m_proc;
private MyFragment m_frag;
public MyClass(MyFragment fr)
{
m_proc = new MyProc();
m_frag = new MyFrag();
m_frag.proc();
}
}
For the method void proc() of class MyFragment I can not change not signature ,nor return type. But can change the implementation
My goal is to update m_proc of MyClass with some data generated inside MyFragment::proc()
I thought about :
Generate inside MyFragment ,the object from MyProc class, populate it in the MyFragment::proc()
and after that copy it to MyClass.m_proc.
On the other hand I don`t like to much the idea of copying...how can it be done more effectively
You can write another method, which accepts MyProc as argument, and call this method from proc:
public class MyFragment
{
/// members + methods
public void proc()
{
// just pass dummy argument
ProcEx(new MyProc());
}
public void ProcEx(MyProc myProc)
{
// fill myProc
}
}
public class MyClass
{
private MyProc m_proc;
private MyFragment m_frag;
public MyClass(MyFragment fr)
{
m_proc = new MyProc();
m_frag = new MyFrag();
m_frag.ProcEx(m_proc);
}
}
P.S. CPP-styled member names drives me crazy.
Related
I’m working with a state pattern and are wondering how to define variables so they can use in each child class. A protected variable in the abstract parent class may be the right choice, but with this, I’m wondering how to initialize these variables from the main class.
class Main
{
\\Initialize variable "file" here?
\\...
Context tc = new Context(new Step01());
\\...
}
class Context
{
private State ts;
// Constructor
public Context(State st)
{
this.State = st;
}
// Gets or sets the state
public State State
{
get
{
return st;
}
set
{
st = value;
}
}
public void Request()
{
ts.Handle(this);
}
}
abstract class State
{
protected string file = "file";
public abstract void Handle(Context tc);
}
class Step01 : State
{
tc.State = new Step02();
// use variable "file"
}
class Step02 : State
{
tc.State = new Step0x()
// use variable "file"
}
The example is a code snipped and don't work. I hope it helps to explain my question more accurate.
The quantity of child classes (Step0x) varies, so I think it's easier to define the variable only once in the parent class.
Does anybody have an idea how to initialize my variables in the main class?
Thank you.
Define file as constant:
abstract class State
{
protected const string file = "file";
public abstract void Handle();
}
Here is implementation of Step01 and Step02 which are using file:
class Step01 : State
{
public override void Handle(){}
public void PrintFile()
{
Console.WriteLine(string.Format("step1 + {0}", file));
}
}
class Step02 : State
{
public override void Handle(){}
public void PrintFile()
{
Console.WriteLine(string.Format("step2 + {0}", file));
}
}
And here is usage of the Step01 and Step02 classes:
static void Main(string[] args)
{
Step01 step1 = new Step01();
step1.PrintFile();
Step02 step2 = new Step02();
step2.PrintFile();
Console.ReadLine();
}
How can I add a method from class A to a delegate of class B without knowing in advance which method I will be adding and what class A is? And then call that delegate from class A?
class Class {
public string someProperty;
public delegate void myDelegate(Class obj);
myDelegate handler = new myDelegate(mainClassMethod); //here is the problem..
public void someMethod() {
handler();
}
}
class MainClass {
public static void Main() {
Class classObj = new Class();
classObj.someProperty = "hello";
public void mainClassMethod(Class obj) {
System.Console.WriteLine(obj.someProperty);
}
classObj.someMethod();
}
}
Should I use something other than delegates for this? By the way I am doing this in C#!
make mainClassMethod static and access it via class name MainClass. Also you cant declare nested functions as class members, you need to declare mainClassMethod separately.
class MainClass {
public static void Main()
{
Class classObj = new Class();
classObj.someProperty = "hello";
classObj.someMethod();
}
public static void mainClassMethod(Class obj)
{
System.Console.WriteLine(obj.someProperty);
}
}
Also you declared delegate void myDelegate(Class obj); so you need to pass instance of a Class as a parameter. In my example I pass object found by this reference, which is an object that you call someMethod at.
Now you can write:
class Class {
public string someProperty;
public delegate void myDelegate(Class obj);
myDelegate handler = new myDelegate(MainClass.mainClassMethod); //no error
public void someMethod()
{
handler(this);
}
}
I think I couldnt do this thing, but I try to ask (maybe :)).
Suppose I have this Main class :
public class UiUtils
{
public static MyObject myObject;
public UiUtils()
{
myObject=new MyObject();
}
}
now if I want to try to call this instance from another Context Class (web application), I do this :
public partial class context_eventi_CustomClass : System.Web.UI.UserControl
{
protected void Page_Load(object sender, EventArgs e)
{
Console.Write(UiUtils.myObject.Title());
}
}
but what I'd like to do is this :
public partial class context_eventi_CustomClass : System.Web.UI.UserControl
{
protected void Page_Load(object sender, EventArgs e)
{
Console.Write(myObject.Title());
}
}
so, use directly myObject and not UiUtils.myObject :)
I think this is not possible, but maybe I wrong and there are any strategies :) Thanks
** EDIT **
my solution for the moment :
public class UiUtils
{
public static MyObject myObject;
public UiUtils()
{
myObject=new MyObject();
iContext.myObject = myObject;
}
}
public class iContext : System.Web.UI.UserControl
{
public static MyObject myObject;
public iContext()
{
}
public iContext(MyObject myObject)
{
myObject = myObject;
}
}
public partial class context_eventi_CustomClass : iContext
{
protected void Page_Load(object sender, EventArgs e)
{
Console.Write(myObject.Title());
}
}
seems to works! What do you think about?
Per MSDN,
A static method, field, property, or
event is callable on a class even when
no instance of the class has been
created. If any instances of the class
are created, they cannot be used to
access the static member. Only one
copy of static fields and events
exists, and static methods and
properties can only access static
fields and static events. Static
members are often used to represent
data or calculations that do not
change in response to object state.
and
"To access a static class member, use the name of the class instead of a variable name to specify the location of the member."
and
The static member is always accessed
by the class name, not the
instance name
#Daniel Earwicker says in his answer on SO here:
...Static members fail to integrate
well with inheritance. It makes no
sense to have them heritable. So I
keep static things in separate static
classes...
So I am not clear on your design why MyObject needs to be static. All you are trying to save is a little typing, but inheritance will not help you here either.
Edit:
I tried to replicate your code in a simple console application. The output is not what you would expect:
namespace ConsoleApplication1
{
public class UiUtils
{
public static int myObject = 1;
public UiUtils()
{
myObject = new int();
iContext.myObject = myObject;
Console.WriteLine("This is UiUtils\n");
}
}
public class iContext
{
public static int myObject = 2;
public iContext()
{
Console.WriteLine("This is iContext\n");
}
public iContext(int myObject)
{
myObject = myObject;
}
}
public class iContext2 : iContext
{
public static int myObject = 3;
public iContext2()
{
Console.WriteLine(myObject.ToString() + "\nThis is iContext2\n");
Console.WriteLine(iContext.myObject.ToString());
}
}
class Program
{
static void Main(string[] args)
{
iContext2 icontext = new iContext2();
Console.In.ReadLine();
}
}
}
The output ends up being this:
This is iContext
3
This is iContext2
If you add a call to iContext.myObject, then it outputs it's number:
This is iContext
3
This is iContext2
2
To access the object without typing the class you can use inheritance.
public class CustomClass : UiUtils
This will share UiUtils properties with CustomClass
I have a private abstract class called TDSeq in which there are some abstract members and non-abstract members. There are 2 derived classes which it gets data from:- private class TDSeqBuy: TDSeq and private class TDSeqSell: TDSeq.
The members from the private abstract class that I am trying to access are private/public bools/doubles/integers.
The data flows from the derived classes through to the private abstract class by protected abstract name {get;}. After which the data is "moved" to the above mentioned private/public bool/doubles/integers.
I would like to access data for read-only purposes from the abstract class to a public class but do not know how to do that. Could someone please help?
private abstract class TDSeq
{
public event SetupCompletedEventHandler SetupCompleted;
protected abstract double TDSTHigh { get; }
protected abstract double TDSTLow { get; }
protected abstract double SetupStopLevel { get; }
public double highesthigh = 0;
public double lowestlow = 0;
public double truerange = 0;
public double setupstoplevel = 0;
// ...
case TDSTStateSetup.Completed:
if( ValidSetup )
{
Print = "ValidExtSetup";
setupCount++;
SetupDrawText();
//Print = NameIndex;
}
else
{
Print = "ExtSetup Finalised";
tdsetupiscompleted = true;
if (tdsetupiscompleted)
{
Print = "tdsetupiscompleted";
}
if (tdsetupdirection == 1)
{
Print = "tdsellsetupiscompleted";
}
if (tdsetupdirection == -1)
{
Print = "tdbuysetupiscompleted";
}
highesthigh = TDSTHigh;
lowestlow = TDSTLow;
truerange = (highesthigh - lowestlow);
setupstoplevel = SetupStopLevel;
stateSetup = TDSTStateSetup.Finished;
}
// ...
}
I'm trying to publicly access the last 5 lines...
You can also use auto properties to acheive the same without using a private field.
e.g.
private abstract class A
{
protected int Number { get; private set; }
}
private class B : A
{
public int GetNumber()
{
return Number;
}
}
Use protected, not private. Also consider composition over inheritance.
Nested classes are not a good idea. It only limits scope. And protected will not save you there.
If you want access to the properties and them only to be read only, store the values in private fields - and give a protected get property to give read only access to the private fields like so:
private abstract class A
{
private int _number = 5;
protected int Number { get { return _number; } }
}
private class B : A
{
public int GetNumber()
{
return Number;
}
}
private class C : A
{
public int GetNumber()
{
return Number;
}
}
If you want to access data via an object of an abstract class A within a method of a separate, public class X, the abstract class has to be visible to X, so it has to be public (or at least internal, when A and X are part of the same assembly):
public class Program
{
static void Main(string[] args)
{
B b = new B();
X.Test(b);
}
// private does not work here if you want to have a parameter of type A in X
public abstract class A
{
private int _number = 5;
public int Number { get { return _number; } }
}
private class B : A
{
}
}
public class X
{
public static void Test(Program.A a)
{
Console.WriteLine(a.Number);
}
}
Top level classes in an assembly can only be public or internal in terms of accessibility, so I'm assuming your private abstract class and it's derived classes are all nested inside some public class, for starters. Correct?
If so, simply access members of the nested private abstract class that are non-abstract and public by first instantiating the private derived classes inside that parent class via say a public property, then simply call the public field from it:
public class TopClass
{
DerivedClass MyDerivedClass;
public int GetDerivedClassPublicField
{
get
{
DerivedClass MyDerivedClass = new DerivedClass();
return DerivedClass.myfield;//here is access to your abstract class field from outside
}
}
// Private classes must be nested
private abstract class AbstractClass
{
public int myfield = 1;
}
private class DerivedClass : AbstractClass
{
... (derived classes inherit the non-abstract field from the abstract parent by default here) ...
}
}
// now call the public top level class property to get the field in the abstract class
TopClass MyTopClass = new TopClass();
int myInt = MyTopClass.GetDerivedClassPublicField;
I am experimenting with calling delegate functions from a delegate array. I've been able to create the array of delegates, but how do I call the delegate?
public delegate void pd();
public static class MyClass
{
static void p1()
{
//...
}
static void p2 ()
{
//...
}
//...
static pd[] delegates = new pd[] {
new pd( MyClass.p1 ),
new pd( MyClass.p2)
/* ... */
};
}
public class MainClass
{
static void Main()
{
// Call pd[0]
// Call pd[1]
}
}
EDIT: The reason for the array is that I need to call the delegate functions by an index as needed. They are not run in response to an event. I see a critical (stupid) error in my code as I had tried to execute the delegate function using the pd[] type rather than the name of the array (delegates).
If they're all the same type, why not just combine them into a single multicast delegate?
static pd delegateInstance = new pd(MyClass.p1) + new pd(MyClass.p2) ...;
...
pd();
public class MainClass
{
static void Main()
{
pd[0]();
pd[1]();
}
}
In .Net, any delegate is in fact actually a "multicast" delegate (it inherits from this built-in base class), and therefore contains an internal linked list which can contain any number of target delegates.
You can access this list by calling the method GetInvocationList() on the delegate itself. This method returns an array of Delegates...
The only restriction is that all the delegates inside of a given delegate's linked list must have the same signature, (be of the same delegate type). If you need your collection to be able to contain delegates of disparate types, then you need to construct your own list or collection class.
But if this is ok, then you can "call" the delegates in a given delegate's invocation list like this:
public delegate void MessageArrivedHandler(MessageBase msg);
public class MyClass
{
public event MessageArrivedHandler MessageArrivedClientHandler;
public void CallEachDelegate(MessageBase msg)
{
if (MessageArrivedClientHandler == null)
return;
Delegate[] clientList = MessageArrivedClientHandler.GetInvocationList();
foreach (Delegate d in clientList)
{
if (d is MessageArrivedHandler)
(d as MessageArrivedHandler)(msg);
}
}
}
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
pd[0]();
pd[1]();
}
public delegate void delegates();
static delegates[] pd = new delegates[]
{
new delegates(MyClass.p1),
new delegates(MyClass.p2)
};
public static class MyClass
{
public static void p1()
{
MessageBox.Show("1");
}
public static void p2()
{
MessageBox.Show("2");
}
}
}
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
pd[0](1);
pd[1](2);
}
public delegate void delegates(int par);
static delegates[] pd = new delegates[]
{
new delegates(MyClass.p1),
new delegates(MyClass.p2)
};
public static class MyClass
{
public static void p1(int par)
{
MessageBox.Show(par.ToString());
}
public static void p2(int par)
{
MessageBox.Show(par.ToString());
}
}
}