I have the abstract class shown below. It's nested class B is where I would like to define new functions.
public abstract class A {
public string varA = "Default";
public class B {
public B() {
}
public abstract somethingCool(int[] val);
}
}
public class C:A {
//set B functions
}
Is there a particular reason you NEED B to be a nested class? Why not just let your A class have a property of type B? Also, the somethingCool method needs a return type.
public abstract class A
{
public string varA = "Default";
public B InstanceOfB { get; set; }
}
public abstract class B
{
public abstract void SomethingCool(int[] val);
}
public class C : A
{
public override void SomethingCool(int[] val)
{
//do something cool
}
}
I'm not sure what you are trying to do, but if you want to implement B's functions from C, then mark B as abstract and subclass it in C. You can then override the abstract somethingCool method. Something like this:
public abstract class A
{
public string varA = "Default";
public abstract class B
{
public B() {}
public abstract void somethingCool(int[] val);
}
public void Foo(B bar, int[] val)
{
bar.somethingCool(val);
}
}
public class C : A
{
// set B functions
public class D : A.B
{
public override void somethingCool(int[] val)
{
for (int i = 0; i < val.Length; ++i)
{
System.Console.Write(string.Format("{0} ", val[i]));
}
}
}
}
Note that you can also subclass B from outside C:
public class E : A.B
{
public override void somethingCool(int[] val)
{
for (int i = val.Length - 1; i >= 0; --i)
{
System.Console.Write(string.Format("{0} ", val[i]));
}
}
}
Results:
public class Test
{
public void Test()
{
int[] val = new int[] { 1, 2, 3 };
var C = new C();
var D = new C.D();
C.Foo(D, val); // should print 1 2 3
var E = new E();
C.Foo(E, val); // should print 3 2 1
}
}
Please first take a look at this simple code;
This is my base class:
public class BaseClass
{
public BaseClass()
{
}
public BaseClass(BaseClass b)
{
}
public virtual string GetMSG()
{
return "Base";
}
}
and this is the derived one:
public class DrivenClass : BaseClass
{
public string MSG { get; set; }
public DrivenClass(string msg)
{
MSG = msg;
}
public DrivenClass(DrivenClass d)
{
MSG = d.MSG;
}
public override string GetMSG()
{
return MSG;
}
}
and this is the test:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
public BaseClass B { get; set; }
public DrivenClass D { get; set; }
private void button1_Click(object sender, EventArgs e)
{
D = new DrivenClass("Driven");
B = new BaseClass(D);
MessageBox.Show("B:" + B.GetMSG() + "\nD:" + D.GetMSG());
}
}
Now my question is what should I do that B = new BaseClass(D); works like B = new DrivenClass(D); ?
I'm using this in polymorphism and I like to use one copy-constructor instead of different driven ones.
I want the output like this :
Driven
Driven
but now it's like this :
Base
Driven
You can use an overridden virtual Copy method instead of a copy constructor.
public class BaseClass
{
public BaseClass()
{
}
public virtual BaseClass ShallowCopy()
{
return new BaseClass();
}
public virtual string GetMSG()
{
return "Base";
}
}
public class DrivenClass : BaseClass
{
public string MSG { get; set; }
public DrivenClass(string msg)
{
MSG = msg;
}
public override BaseClass ShallowCopy() {
return new DrivenClass(this.MSG);
}
public override string GetMSG()
{
return MSG;
}
}
Then call it like this:
D = new DrivenClass("Driven");
B = D.ShallowCopy();
This will work because calling a virtual method always calls the actual overriden implementation in the subclass, even when called from the baseclass interface.
What happens is normal because you create new instance of base class here. Therefore you never override the GetMSG method:
B = new BaseClass(D);
What you wanted to do is to have the same public class:
public BaseClass B { get; set; }
and to give it the value of new DrivenClass(D)
B = new DrivenClass(D);
I am setting a property of base class from derived class as following:
public abstract class Coverter
{
public Mydata data { get; set; }
public abstract void Convert();
}
public class Mydata
{
public int i;
}
public class Coverter1 : Coverter
{
public Coverter1(Mydata data1)
{
data = data1;
}
public override void Convert()
{
Console.WriteLine(data.i.ToString());
}
}
private static void Main(string[] args)
{
Mydata data = new Mydata();
data.i = 5;
Coverter c = new Coverter1(data);
c.Convert();
Console.ReadLine();
}
Is there any flaw with this kind of implementation ? What could be the better approach?
I can do the same thing in the following approach.
public abstract class Coverter
{
public Mydata data { get; set; }
public abstract void Convert();
}
public class Mydata
{
public int i;
}
public class Coverter1:Coverter
{
override public void Convert()
{
Console.WriteLine(data.i.ToString());
}
}
static void Main(string[] args)
{
Mydata data1 = new Mydata();
data1.i = 5;
Coverter c = new Coverter1();
c.data = data1;
c.Convert();
Console.ReadLine();
}
Which appraoch is better?
Pass the field down in the constructor. (Note: normally you should name fields starting with a lower case character and properties with uppercase). Here is an example where I fixed the naming.
public abstract class Converter
{
private readonly MyData data;
protected Converter(MyData data)
{
this.data = data;
}
public MyData Data { get { return data; } }
}
public class MyData
{
private readonly int value;
public MyData(int value)
{
this.value = value;
}
public int MyValue { get { return value; } }
}
public class Converter1 : Converter
{
public Converter1()
: base(new MyData(5))
{
}
}
I recommend the practice of using readonly fields and getters only for properties to start with. Doing so will make your types immutable which usually helps get your program correct initially. Start off immutable and then introduce mutability where you need it, and only once you need it. Having the types immutable like this requires passing the values through the constructor.
Imagine a class as follows.. It's a class provided to me to work with.. I cannot change its source..
public class MyClass
{
object _Object { get; set; }
public void FuncA1() { _Object = new object(); }
public void FuncA2() { _Object = new List<object>(); }
public int FuncB1() { _Object = 0; return 0; }
public int FuncB2() { _Object = 123; return 123; }
public string FuncC1() { _Object = null; return null; }
public string FuncC2() { _Object = "Hello"; return "Hello"; }
}
Im trying to create a wrapper for this class, such that I can group its many functions into categories..
MyWrapper.Voids.FuncA1();
MyWrapper.Voids.FuncA2();
MyWrapper.Integers.FuncB1();
MyWrapper.Integers.FuncB2();
MyWrapper.Strings.FuncC1();
MyWrapper.Strings.FuncC2();
The only solution I can think of for this scenario is to design the wrapper like this:
public class MyWrapper
{
MyClass _Instance { get; set; }
public _Void Voids { get; private set; }
public _Integer Integers { get; private set; }
public _String Strings { get; private set; }
public class _Void
{
MyWrapper _Parent { get; set; }
public void FuncA1() { _Parent._Instance.FuncA1(); }
public int FuncA2() { return _Parent._Instance.FuncA2(); }
}
public class _Integer
{
...
}
public class _String
{
...
}
public MyWrapper()
{
_Instance = new MyClass();
Voids = new _Voids(this);
Integers = new _Integer(this);
Strings = new _String(this);
}
}
This solution works, but has a number of problems:
- The inner classes are forced to be public, which allows them to be instantiated by the user..
- I am forced to maintain a reference of the parent object in the child classes..
Is there a better way of doing this?
EDIT: The code posted initially was a bit confusing, in the sense that it was diverting attention away from the core issue and more into the issues of whether a function would cause exceptions or not if they all work on the same object..
NOTE: This is not actual code.. I hacked together this example to show what I'm trying to do.. CREATE A WRAPPER AROUND AN OBJECT (I cannot change the original object's code) AND GROUP FUNCTIONS INTO CATEGORIES..
FINAL EDIT: following suggestion by Juharr.. here's what ive done to accomplish what i wanted.. for the betterment of others..
public interface IVoid
{
void FuncA1();
void FuncA2();
}
public interface IInteger
{
int FuncB1();
int FuncB2();
}
public class MyWrapper
{
public MyClass Instance { get; private set; }
public IVoid Voids { get; private set; }
public IInteger Integers { get; private set; }
private abstract class MyBase
{
protected MyWrapper Parent { get; set; }
protected MyClass Instance { get { return Parent.Instance; } }
public MyBase(MyWrapper oParent) { Parent = oParent; }
}
private class MyVoid : MyBase, IVoid
{
public MyVoids (MyWrapper oParent) : base(oParent) { }
public void FuncA1() { Instance.FuncA1(); }
public void FuncA2() { Instance.FuncA2(); }
}
private class MyInteger : MyBase, IInteger
{
public MyInteger (MyWrapper oParent) : base(oParent) { }
public int FuncB1() { return Instance.FuncB1(); }
public int FuncB2() { return Instance.FuncB2(); }
}
public MyWrapper()
{
Instance = new MyClass();
Voids = new MyVoid(this);
Integers = new MyInteger(this);
}
}
You could write public interfaces instead. Then your inner classes don't have to be public. So something like this.
public interface IIntger
{
void Set(int iValue);
int Get();
}
public class MyWrapper
{
MyClass _Instance { get; set; }
public IInteger Integer { get; private set; }
private class _Integer : IInteger
{
MyWrapper _Parent { get; set; }
public void Set(int iValue) { _Parent._Instance.IntegerSet(iValue); }
public int Get() { return _Parent._Instance.IntegerGet(); }
}
public MyWrapper()
{
_Instance = new MyClass();
Integer = new _Integer(this);
}
}
EDIT:
To answer the second part of your question you will either need the reference to the parent class or a reference to the class you are wrapping. So you could have this instead.
public class MyWrapper
{
public IInteger Integer { get; private set; }
private class _Integer : IInteger
{
MyClass _Instance { get; set; }
public _Integer(MyClass myClass) { _Instance = myClass; }
public void Set(int iValue) { _Instance.IntegerSet(iValue); }
public int Get() { return _Instance.IntegerGet(); }
}
public MyWrapper(MyClass instance)
{
Integer = new _Integer(instance);
}
}
Please excuse bursts of stupidity as I learn the intricacies of C# / .NET
Say I have three classes with multiple static properties (more than three but for arguments sake..)
CLASS FOO
public static A
{
get / set A;
}
public static B
{
get / set B;
}
public static C
{
get / set C;
}
CLASS BAR
{
get / set A;
}
public static B
{
get / set B;
}
public static C
{
get / set C;
}
CLASS YOO
{
get / set A;
}
public static B
{
get / set B;
}
public static C
{
get / set C;
}
And from another class I need to update one or several static properties in each class multiple times... How do I keep from writing multiple SWITCH statments like this...
public void updateVarx(string class, string varx)
{
string y = 'class'
SWITCH (y)
{
case FOO:
FOO.A = Varx;
break;
case BAR:
BAR.A = Varx;
break;
case YOO:
YOO.A = Varx;
break;
}
}
And then another one when I want to update B varY:
public void updateVary(string class, string vary)
{
string y = 'class'
SWITCH (y)
{
case FOO:
FOO.B = Vary;
break;
case BAR:
BAR.B = Vary;
break;
case YOO:
YOO.B = Vary;
break;
}
}
Since you are learning .net/c#, I guess i should warn you, using static properties is probably not the way to go in object oriented programming.
Static is global state and is dangerous. If you end up using multi-threaded code, you have to be super careful. If you need only one instance, just instantiate one, but don't go creating static properties on a class, unless you have a pretty good reason to add them (And I can't think of any right now).
In fact, in well designed, object oriented code you sould probably not have many if, switch, getters or setters either.
Let's say you need different behaviors on your classes, you can do it this way.
Interface ISecurity {
void UpdateVarX(int value);
void UpdateVarY(int value);
int GetValueX();
int GetValueX();
}
class Foo:ISecurity {
// Implement methods of the interface
}
class Bar:ISecurity {
// Implement methods of the interface
}
class Yoo:ISecurity {
// Implement methods of the interface
}
// This class is the class that uses your other classes
class Consumer
{
private ISecurity sec;
public Consumer(ISecurity sec) {
sec.UpdateVarX(25);
}
}
Or if as in your example, all your static classes have the same properties:
public class Settings {
public int A {get; set;}
public int B {get; set;}
public int C {get; set;}
}
public class NeedsToUseOtherClass {
public NeedsToUseOtherClass() {
Settings foo = new Settings();
Settings bar = new Settings();
Settings yoo = new Settings();
foo.setA(25);
}
}
Maybe I am not understanding the problem but if all your classes have the same exact properties then you can just pass the object (FOO, BAR, or YOO) into UpdateVarx or UpdateVary methods and just implement an interface? Something along these lines:
public class FOO : IHasStatus
{
public A
{
get / set A;
}
public B
{
get / set B;
}
public C
{
get / set C;
}
}
public void updateVarx(IHasStatus someObject, string varx)
{
someObject.A = varx;
}
public void updateVary(IHasStatus someObject, string vary)
{
someObject.B = vary;
}
If you don't need the concrete classes, you can abstract out the logic like so:
public class Status {
public string A {
get; set;
}
public string B {
get; set;
}
public string C {
get; set;
}
}
public static class StatusManager {
private static Dictionary<string, Status> statusMap = new Dictionary<string,Status>();
public static Status GetStatus(string name) {
Status status;
if (!statusMap.TryGetValue(name, out status))
statusMap[name] = status = new Status();
return status;
}
public static void SetStatus(string name, Status status) {
statusMap[name] = status;
}
public static void UpdateVarx(string name, string varx) {
GetStatus(name).A = varx;
}
// ...
}
If you are a fan of the javascript way of solving multiple switch cases like this
you can always wrap up the switch handlers as Actions and toss them in a Dictionary.
For example : (Source obtained from here)
public class SwitchCase : Dictionary<string,Action>
{
public void Eval(string key)
{
if (this.ContainsKey(key))
this[key]();
else
this["default"]();
}
}
//Now, somewhere else
var mySwitch = new SwitchCase
{
{ "case1", ()=>Console.WriteLine("Case1 is executed") },
{ "case2", ()=>Console.WriteLine("Case2 is executed") },
{ "case3", ()=>Console.WriteLine("Case3 is executed") },
{ "case4", ()=>Console.WriteLine("Case4 is executed") },
{ "default",()=>Console.WriteLine("Default is executed") },
};
mySwitch.Eval(c);
Below code uses all kinds of hacks, not really recommended in production code unless you have a very good reason.
using System;
using System.Linq;
namespace ConsoleApplication1
{
static class Program
{
private static void SetStaticProperty(string className, string propName, string varx)
{
//This sucks, I couldnt find the namespace with easily through reflection :(
string NAMESPACE = "ConsoleApplication1";
Type t = Type.GetType(NAMESPACE + "." + className);
t.GetProperties().Where(p => p.Name == propName).First().SetValue(null, varx, null);
}
public static void updateVarx(string className, string varx)
{
SetStaticProperty(className, "A", varx);
}
public static void updateVary(string className, string vary)
{
SetStaticProperty(className, "B", vary);
}
static void Main(string[] args)
{
updateVarx("Foo", "FooAstring");
updateVarx("Bar", "BarAstring");
updateVarx("Yod", "YodAstring");
updateVary("Foo", "FooBstring");
updateVary("Bar", "BarBstring");
updateVary("Yod", "YodBstring");
Console.WriteLine(Foo.A);
Console.WriteLine(Foo.B);
Console.WriteLine(Bar.A);
Console.WriteLine(Bar.B);
Console.WriteLine(Yod.A);
Console.WriteLine(Yod.B);
Console.ReadLine();
}
}
class Foo
{
public static string A { get; set; }
public static string B { get; set; }
public static string C { get; set; }
}
class Bar
{
public static string A { get; set; }
public static string B { get; set; }
public static string C { get; set; }
}
class Yod
{
public static string A { get; set; }
public static string B { get; set; }
public static string C { get; set; }
}
}
You can use dictionary as configuration and remove the switch statement
Create a dictionary and add append data as below for mapping
//Have dictionary setted up
Dictionary<string, dynamic> m_Dictionary = new Dictionary<string, dynamic>();
m_xmlDictionary.Add("classA",FOO);
m_xmlDictionary.Add("classB",BAR);
m_xmlDictionary.Add("classC",BAR);
//Have dictionary setted up
//change the function as below
public void updatevarx(string class, string varx)
{
m_Dictionary[class].A=varx // Replaced switch statement
}
//while calling use
updatevarx("classC","abc!");// This will assign BAR.A with abc!