C# editing and adding function to nested class of abstract class - c#

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
}
}

Related

C# hide method FOR baseclass

I wonder if something like this is possible in C#:
public class A
{
public string Foo() { return "Foo"; }
}
public class B : A
{
public string Bar() { return Foo(); }
}
public class C : B
{
public new string B.Foo() { return "Bar"; } // Hide A.Foo in B
}
Main()
{
C c = new C();
Console.WriteLine(c.Bar()); // Want to get "Bar"
}
by public new string B.Foo() { return "Bar"; } I mean do something in C (without changing A or B) that has the equivalent result as if public new string Foo() { return "Bar"; } was implemented in B. So, hide a method FOR a base class OF a base further up the inheritance hierarchy.
What you want is virtual, which allows you to override base behavior in the inheriting type.
public class A
{
public virtual string Foo() { return "Foo"; }
}
public class B : A
{
public virtual string Bar() { return Foo(); }
}
public class C : B
{
public override string Foo() { return "Bar"; } // Hide A.Foo in B
}
This outputs "bar"

overloading with runtime type in c#

Consider following code:
public class A
{
public A(){}
}
public class B:A
{
public B(){}
}
public class C
{
public C(){}
public void fun(A a)
{
Console.WriteLine("that was A");
}
public void fun(B b)
{
Console.WriteLine("that was B");
}
}
public class Program
{
public static void Main()
{
A a = new A(), b = new B();
C c = new C();
c.fun(a);
c.fun(b);
}
}
In the current form, it says "that was A" twice. How to fix class C, so that fun(B b) is invoked when b's runtime type is B, but compilation type is A? Currently it works properly only when I declare b as B during compilation.
#Edit: without checking types with ifs etc.
Invoke fun via a virtual method.
public class A
{
public virtual void fun(C c)
{
c.fun(this);
}
}
public class B:A
{
public override void fun(C c)
{
c.fun(this);
}
}
public class C
{
public void fun(A a)
{
Console.WriteLine("that was A");
}
public void fun(B b)
{
Console.WriteLine("that was B");
}
}
public class Program
{
public static void Main()
{
A a = new A(), b = new B();
C c = new C();
a.fun(c);
b.fun(c);
}
}
Output:
that was A
that was B
See example on Fiddle

How to write 2 classes with the same method and inheritance?

I have X classes with different information and calculation methods that should be shared but could be overwritten, so:
class Rule1 {
int type = 1;
string name = "Rule";
public float Calc()
{
return 1 + 2 + type; // SAME
}
}
class Rule2 {
int type = 2;
string name = "Rule2";
public float Calc()
{
return 1 + 2 + type; // SAME
}
}
class Rule3 {
int type = 3;
string name = "Rule3";
public float Calc()
{
return 3 + 4 + type; // DIFFERENT
}
}
What I want to write in the calling methods are like this:
class Calculator
{
public void Do(List<IRules> ruleList)
{
foreach(var rule in ruleList)
{
rule.Calc();
}
}
}
So how would my interface should have to look like and how to abstract the calc method as default implementation but overwriteable?
If you have an implementation that's correct for most inheritors but not all, mark it virtual and override it in a derived class:
public class BaseCalculation
{
public virtual float Calculate()
{
return 42;
}
}
public class HalfCalculation : BaseCalculation
{
public override float Calculate()
{
return 21;
}
}
You can now use the base class, BaseCalculation, instead of an interface. If you insist on still using an interface, then you can still define the Calculate() method in an interface and apply that to your base class:
public interface IRules
{
float Calculate();
}
public class BaseCalculation : IRules
{
// same as above
With the added benefit that you can apply this interface to other classes that also calculate something, but without any of the logic that's in BaseCalculation.
You can try this using an asbtract base class and polymorphism on Calc.
What is polymorphism
No need to use interface unless you have a real and good reason to do that.
What is the difference between an interface and a class
We use a protected constructor to propagate the parameters.
class Calculator
{
public void Do(List<RuleBase> ruleList)
{
foreach ( var rule in ruleList )
{
// do what you want with the result of rule.Calc();
}
}
}
public abstract class RuleBase
{
public int Type { get; private set; }
public string Name { get; private set; }
public abstract float Calc();
protected RuleBase(int type, string name)
{
Type = type;
Name = name;
}
}
public class Rule1 : RuleBase
{
public override float Calc()
{
return 1 + 2 + Type;
}
public Rule1()
: base(1, "Rule1")
{
}
protected Rule1(int type, string name)
: base(type, name)
{
}
}
public class Rule2 : Rule1
{
public Rule2()
: base(2, "Rule2")
{
}
protected Rule2(int type, string name)
: base(type, name)
{
}
}
public class Rule3 : RuleBase
{
public override float Calc()
{
return 3 + 4 + Type;
}
public Rule3()
: base(3, "Rule3")
{
}
protected Rule3(int type, string name)
: base(type, name)
{
}
}
If you want an interface create it and add it to RuleBase:
public interface IRule
{
float Calc();
}
public abstract class RuleBase : IRule
You are searching for inherited class and virtual method (wich allows override) :
class GenericRule {
int type = 1;
string name = "Rule";
public virtual float Calc()
{
return 1 + 2 + type; // SAME
}
}
class Rule3 : GenericRule
{
int type = 3;
string name = "Rule3";
public override float Calc()
{
return 3 + 4 + type; // DIFFERENT
}
}
class Calculator
{
public void Do(List<GenericRule> ruleList)
{
foreach(var rule in ruleList)
{
rule.Calc();
}
}
}
Every class must support the interface. The implementation of method Calc in each class is not important. They can be the same or different.
If you want to have a standard implementation (virtual implementation), you could use a base class and overwrite the method in some classes (in your example Rule3).
If you do not want a standard implmentation (virtual implementation), you could use an abstract base class and overwrite the method in all classes (in your example Rule1, Rule2 and Rule3).
But that has nothing to do with the interface you want to use.
Complete working example (just using the interface):
using System;
using System.Collections.Generic;
namespace Temp
{
class Program
{
static void Main(string[] args)
{
var calc = new Calculator();
var rules = new List<IRule>() { new Rule1(), new Rule2(), new Rule3() };
calc.Do(rules);
Console.WriteLine(calc.GetTotal());
Console.ReadKey();
}
}
public interface IRule
{
float Calc();
}
public class Rule1 : IRule
{
int type = 1;
string name = "Rule";
public float Calc()
{
return 1 + 2 + type; // SAME
}
}
public class Rule2 : IRule
{
int type = 2;
string name = "Rule2";
public float Calc()
{
return 1 + 2 + type; // SAME
}
}
public class Rule3 : IRule
{
int type = 3;
string name = "Rule3";
public float Calc()
{
return 3 + 4 + type; // DIFFERENT
}
}
public class Calculator
{
private float _total = 0;
public void Do(List<IRule> ruleList)
{
foreach (var rule in ruleList)
{
_total += rule.Calc();
}
}
public float GetTotal()
{
return _total;
}
}
}

How to access public Property MyProperty of class A in class C

I have following code:
public class A
{
public int MyProperty {get; set;}
}
public class B
{
A myInstance = new A();
myInstance.MyProperty = 10;
}
public class C
{
public void InvokeA()
{
//How to access MyPropery here?
BInstance = new B();
Console.WriteLine(B.myInstance.MyProperty.ToString());
}
}
I'm looking for a way to access MyProperty as written above. Inheritance is not an option since my class C is already inherited from some base class. A way without declaring any of the given classes as static would be nice!
Thanks,
Orz
Consider following classes:
public class A
{
public int MyProperty { get; set; }
}
public class B
{
public A GetAInstance()
{
A myInstance = new A();
myInstance.MyProperty = 10;
return myInstance;
}
}
public class C
{
private B BInstance;
public void InvokeA()
{
BInstance = new B();
Console.WriteLine(BInstance.GetAInstance());
}
}
and then you will create your C instance in Main:
static void Main(string[] args)
{
C cInstance = new C();
cInstance.InvokeA();
}
In order to accomplish your goal, you need to expose B.MyInstance as a property of the B class, just like you exposed A.MyProperty as a property of the A class.
Edit: Per the comments of others regarding use of the static keyword, here's what you might want your code to look like:
public class A
{
public int MyProperty { get; set; }
}
public static class B
{
static B()
{
MyInstance = new A();
MyInstance.MyProperty = 10;
}
public static A MyInstance { get; set; }
}
public class C
{
// not sure what your intention is here
public C()
{
System.Console.WriteLine(B.MyInstance.MyProperty.ToString()); // "10\n"
}
}
Yes. You can inherits classes from A to B something like this:
public class A
{
public int MyProperty {get; set;}
}
public class B : A
{
public B()
: A()
{
MyProperty = 1;
}
}
Now you can do:
(new B()).MyProperty
Or use Singleton approach to resolve:
public class B
{
private static _a;
public class A
{
public int MyProperty {get; set;}
}
public static A AA {
if (_a == null) {
_a = new A();
}
return _a;
}
}
This implmentation will return
B.A.MyProperty.ToString();

Copy constructor in polymorphism in C#

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);

Categories

Resources