How to handle base class constructors in C#? - c#

I have a class that extends a base class. The base class is more generic, and thus needs more parameters. The derived class is a specific type of base class, and thus only needs one of the two parameters the base class needs in its constructor (the derived class can provide the base class with the second parameter, but needs to do some processing first).
Is it possible to have a constructor in the derived class that then invokes the base classes constructor?
I'm aware I could just use : base(int a, int b) if the parameters were passed in directly, but I don't think I can do this since I need to process the second variable before calling the base class constructor.
class Foo {
private int c;
public Foo(int a, int b) {
c = a + b;
}
}
class Bar : Foo {
public Bar(int a, bool plusOrMinus) {
if (plusOrMinus) {
Foo(a, 5); // calling base class constructor- AFTER processing
} else {
Foo(a, -5); // calling base class constructor- AFTER processing
}
}
}

One way to do this is to use the ternary operator
public Bar(int a, bool plusOrMinos) : base(a, plusOrMinus ? 5 : -5) {
...
}
For more complex conditionals though you should switch to a static factory method
private Bar(int a, int b) : base(a, b) {
...
}
public static Bar Create(int a, bool plusOrMinus) {
if (plusOrMinus) {
return new Bar(a, 5);
} else {
return new Bar(a, -5);
}
}

You can just do it inline, no?
public Bar(int a, bool plusOrMinus) : base(a, plusOrMinus ? 5 : -5) {
}
If you need to do something more sophisticated, you can extract the logic out into a static method:
public Bar(int a, bool plusOrMinus) : base(a, GetValueFromPlusOrMinus(plusOrMinus)) {
}
public static int GetValueFromPlusOrMinus(bool plusOrMinus)
{
if (plusOrMinus)
return 5;
else
return -5;
}

You can more or less do this if you can write a static function to process the data:
class Bar : Foo
{
public Bar(int a, bool plusOrMinus) : base(a, calc(plusOrMinus))
{
}
private static calc(bool pom) : ...; return -5; }
}

My suggestion is to use composition instead of inheritence.
Instead of having a bunch of subclasses (A, B, C) derive from your base class (X), instead have A, B, C contain a private instance of X that they can call.
This way you only have the shared logic in one place (X) and all your classes are able to use it.
class Foo {
private int c;
public Foo(int a, int b) {
c = a + b;
}
}
class Bar {
private Foo _base;
public Bar(int a, bool plusOrMinus) {
if (plusOrMinus) {
_base = new Foo(a, 5);
} else {
_base = new Foo(a, -5);
}
}
}

How about this approach?
class Foo
{
private int c;
public Foo(Builder builder)
{
c = builder.A ?? 0 + builder.B ?? 0;
}
}
class Bar : Foo
{
public Bar()
: base(new Builder().WithA(2).WithB(3).WithPlusOrMinus(false))
{
}
}
public class Builder
{
public int? A { get; private set; }
public int? B { get; private set; }
public bool? PlusOrMinus { get; private set; }
public Builder WithA(int a)
{
A = a;
return this;
}
public Builder WithB(int b)
{
B = b;
return this;
}
public Builder WithPlusOrMinus(bool plusOrMinus)
{
if(!plusOrMinus)
{
B *= -1;
}
return this;
}
}

I would prefer making a protected Initialize(...) on the base class and call this at the end of the ctr in the inherited class.

Related

C# base class extension is called instead of the one for a derived class [duplicate]

This question already has an answer here:
Inheritance and extension method
(1 answer)
Closed last year.
I have class A which is a base class for B. And an extension for both types. Then if I call an extension from a generic function (even with an object of type B) it still calls an extension for a base class
void Main()
{
var b = new B();
GenericClass.SomeGenericFunction<B>(b);
}
public class A
{
public void fooA()
{
Console.WriteLine("A");
}
};
public class B : A
{
public void fooB()
{
Console.WriteLine("B");
}
};
public static class Extension {
public static void SomeMethod(this A a)
{
a.fooA();
}
public static void SomeMethod(this B b)
{
b.fooB();
}
};
public static class GenericClass {
public static void SomeGenericFunction<T>(T someObject) where T : A, new()
{
someObject.SomeMethod();
}
};
The question basically is why the result is?
A
Generic method for reference types shares implementation for all reference types so compiler will resolve SomeMethod only one time during compilation - for "highest" class in hierarchy - A. You can workaround that either by changing A (and B) by making SomeMethod an virtual instance method of A hierarchy or using type checks in your generic function:
public static class GenericClass
{
public static void SomeGenericFunction<T>(T someObject) where T : A, new()
{
switch (someObject)
{
case B b:
b.SomeMethod();
break;
case A:
default:
someObject.SomeMethod();
break;
}
}
}
Or diving into reflection.
try this
public class A
{
public virtual void foo()
{
Console.WriteLine("A");
}
};
public class B : A
{
public override void foo()
{
Console.WriteLine("B");
}
};
public static class Extension
{
public static void SomeMethod(this A a)
{
a.foo();
}
public static void SomeMethod(this B b)
{
b.foo();
}
};
public static class GenericClass
{
public static void SomeGenericFunction<T>(T someObject) where T : A, new()
{
someObject.SomeMethod();
}
};
test
var b = new B();
GenericClass.SomeGenericFunction<B>(b);
result
B
if you need to keep your classes, you can use this code as well. It is easier to extend and mantain. I only don't understand why do you need extensions if you use GenericClass? Maybe it is easier to use as C bellow? Or just use extensions. It seems as they repeat each other.
public static class GenericClass
{
public static void SomeGenericFunction(B someObject)
{
someObject.SomeMethod();
}
public static void SomeGenericFunction(C someObject)
{
someObject.fooC();
}
public static void SomeGenericFunction<T>(T someObject) where T : A, new()
{
someObject.SomeMethod();
}
}

C# Parenting from Generic type of Generic type class? Too complex for me to form more fitting question to the problem :|

I have trouble with figuring out how can I use generic types to solve my problem.
Also I don't know how to describe my problem in short so I will make simplified version of my problem as extended exmplanation.
I am making system for switching quality, transitioning quality levels between different types of 'component' class.
I have base class like:
public abstract class QualityLevel_Base
{
public bool Enabled = true;
public virtual void Transition(QualityLevel_Base a, QualityLevel_Base b, double value)
{
if (value >= 1) Enabled = b.Enabled; else if (value <= 0) Enabled = a.Enabled;
}
protected static double Lerp(double a, double b, double t) { return (1 - t) * a + t * b; }
}
Then I inherit from it like:
public sealed class QualityLevel_LightSource : QualityLevel_Base
{
public double Intensity;
public double Range;
public int ShadowsQuality;
public override void Transition(QualityLevel_Base a, QualityLevel_Base b, double value)
{
QualityLevel_LightSource la = a as QualityLevel_LightSource; // One part of my problem - avoid casting
QualityLevel_LightSource lb = b as QualityLevel_LightSource;
base.Transition(a, b, value);
Intensity = Lerp(la.Intensity, lb.Intensity, value);
/* etc... */
}
}
Then I want to manage quality levels in other class and be able to apply settings onto desired component class.
So I have base class to manage any count of quality levels:
public abstract class QualityManager_Base
{
public Component SourceComponent { get; protected set; }
public List<QualityLevel_Base> QualityLevels { get; protected set; }
public virtual void Initialize(Component component, int qualityLevelsCount)
{
QualityLevels = new List<QualityLevel_Base>();
SourceComponent = component;
AutoQualitySettings(qualityLevelsCount);
}
public virtual void AutoQualitySettings(int qualityLevelsCount) { }
public virtual void ApplyQualitySettings(QualityLevel_Base qualityLevel)
{
SourceComponent.Enabled = qualityLevel.Enabled;
}
}
And I inheriting it for LightSource like:
public sealed class QualityManager_LightSource : QualityManager_Base
{
public LightSource Light { get; private set; }
public override void Initialize(Component component, int qualityLevelsCount)
{
LightSource light = component as LightSource; // Another situation when I would like to avoid casting
Light = light;
base.Initialize(light, qualityLevelsCount);
}
public override void AutoQualitySettings(int qualityLevelsCount)
{
for (int i = 0; i < qualityLevelsCount; i++)
{
QualityLevel_LightSource lightSettings = new QualityLevel_LightSource();
lightSettings.Intensity = Light.Intensity;
lightSettings.Range = Light.Range;
lightSettings.ShadowsQuality = i / qualityLevelsCount;
if (i == qualityLevelsCount - 1) lightSettings.Enabled = false;
}
}
public override void ApplyQualitySettings(QualityLevel_Base qualityLevel)
{
base.ApplyQualitySettings(qualityLevel);
// To my Question: I want to use generic type to avoid casting
QualityLevel_LightSource lightSettings = qualityLevel as QualityLevel_LightSource;
Light.Intensity = lightSettings.Intensity;
Light.Range = lightSettings.Range;
Light.ShadowsQuality = lightSettings.ShadowsQuality;
}
}
Actually I managed to use generic types on this problem making stuff like:
public abstract class QualityLevel_Base<T> where T : QualityLevel_Base<T> { /*...*/ }
public class QualityLevel_LightSource : QualityLevel_Base<QualityLevel_LightSource> { /*...*/ }
public abstract class QualityManager_Base
{
public List<QualityLevel_Base> QualityLevels; // Would like to define it like that but I have to do it
// like that:
public abstract class QualityManager_Base<T> where T : QualityLevel_Base<T>
{
public List<QualityLevel_Base<T>> QualityLevels;
}
Then doing something like this causes error:
public abstract class QualityManager_Base<T> where T : QualityLevel_Base<T>
{
public List<QualityLevel_Base<T>> QualityLevels;
public virtual void AddComponentForQualityManager(Component comp)
{
if (QualityLevels == null) QualityLevels = new List<QualityLevel_Base<T>>();
LightSource light = comp as LightSource;
if (light != null)
{
QualityManager_LightSource lightManager = new QualityManager_LightSource();
QualityLevels.Add(lightManager); // Then I Can't do this because: "cannot convert from 'QualityManager_LightSource' to 'QualityLevel_Base<T>' "
}
/* ... */
}
}
"cannot convert from 'QualityManager_LightSource' to 'QualityLevel_Base'"
There is of course more going on in my system, it is just very simplified version to define my question: How can I avoid casting classes, how can I do it correctly?
Thanks!

Get all concrete implementations of a delegate collection in C# via reflection

Yeah, I tried to make the title smaller, but I couldn't.
I'm very new to reflection, so I'm struggling with a problem that I don't know if it's even possible to solve.
I'll use some simple delegate example to describe it.
public void Main() {
var manager = new EvManager();
var class1 = new Class1(manager);
var class2 = new Class2(manager);
manager.ExecuteIt(5, 12);
/*
This outputs:
In Class1 -> 17
In Class2 -> 18
*/
}
public class EvManager {
public delegate void SumDelegate(int a, int b);
private SumDelegate sum;
public void AddDelegate(SumDelegate s) {
sum += s;
}
public void ExecuteIt(int a, int b) {
sum.Invoke(a, b);
}
}
public class Class1 {
public Class1(EvManager m) {
m.AddDelegate(MySum);
}
private void MySum(int a, int b) {
Console.Write("In Class1 -> " + (a + b));
}
}
public class Class2 {
public Class2(EvManager m) {
m.AddDelegate(MyOtherSum);
}
private void MyOtherSum(int a, int b){
Console.Write("In Classe2 -> " + (a + b));
}
}
Okay, that's the example. What do I want from it? I want, through the EvManager "sum" delegate property be able to access the concrete implementations of all the methods that it invokes.
This is basically what I want:
class EvManager {
private SumDelegate sum;
public void ExecuteIt(int a, int b) {
var invocationList = sum.GetInvocationList();
foreach (var m in invocationList) {
// m is a reference to the annonymous call.
// Through reflection, I want to access the concrete method name.
// In this case, the first iteration "MySum", and the second "MyOtherSum"
// Is this possible?
// Like...
// var concreteMethodName = m.GetMethod().ConcreteCallerType.GetMethod(m.GetConreteMethodName());
// Or something like that?
}
}
}
Hope I made my problem clear, this is killing me.
The Method property holds the information about the real method:
var mName = m.Method.Name;
You can add the following method to EvManager:
public void ListDelegates()
{
foreach (var m in sum.GetInvocationList())
{
Console.WriteLine(m.Method.Name);
}
}
Calling it will give you what you want:
MySum
MyOtherSum
Take a look here on a Delegate class reference.
Actually, it is very simple. Use the Method property.
Check this code:
using System;
namespace ConsoleApplication2
{
public class EvManager
{
public delegate int SumDelegate(int a, int b);
private SumDelegate sum;
public void AddDelegate(SumDelegate s)
{
sum += s;
}
public void ExecuteIt(int a, int b)
{
foreach (var m in sum.GetInvocationList())
{
Console.WriteLine("{0}({1}, {2}) = {3}", m.Method.Name, a, b, m.DynamicInvoke(a, b));
}
}
}
public class Class1
{
public Class1(EvManager m)
{
m.AddDelegate(FakeSum);
}
public int FakeSum(int a, int b)
{
return a - b;
}
}
public class Class2
{
public Class2(EvManager m)
{
m.AddDelegate(RealSum);
}
public int RealSum(int a, int b)
{
return a + b;
}
}
class Program
{
static void Main(string[] args)
{
var manager = new EvManager();
var class1 = new Class1(manager);
var class2 = new Class2(manager);
manager.ExecuteIt(5, 12);
}
}
}
Output:
FakeSum(5, 12) = -7
RealSum(5, 12) = 17
You can get the MethodInfoof each one of your split up delegates through the Method Property of the Delegate which has Name property.
class EvManager {
private SumDelegate sum;
public void ExecuteIt(int a, int b) {
var invocationList = sum.GetInvocationList();
foreach (var m in invocationList) {
var concreteMethodName = m.Method.Name;
}
}
}

inherit from two classes in C# [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Multiple Inheritance in C#
I have two classes Class A and Class B. These two classes cannot inherit each other. I am creating new class called Class C. Now, I want to implement the methods in class A and class B by inheriting. I am aware that multiple inheritance is not possible in C# but is there any other way to do this?
Multitiple inheritance is not possible in C#, however it can be simulated using interfaces, see Simulated Multiple Inheritance Pattern for C#.
The basic idea is to define an interface for the members on class B that you wish to access (call it IB), and then have C inherit from A and implement IB by internally storing an instance of B, for example:
class C : A, IB
{
private B _b = new B();
// IB members
public void SomeMethod()
{
_b.SomeMethod();
}
}
There are also a couple of other alternaitve patterns explained on that page.
An common alternative to inheritance is delegation (also called composition): X "has a" Y rather than X "is a" Y.
So if A has functionality for dealing with Foos, and B has functionality for dealing with Bars, and you want both in C, then something like this:
public class A() {
private FooManager fooManager = new FooManager(); // (or inject, if you have IoC)
public void handleFoo(Foo foo) {
fooManager.handleFoo(foo);
}
}
public class B() {
private BarManager barManager = new BarManager(); // (or inject, if you have IoC)
public void handleBar(Bar bar) {
barManager.handleBar(bar);
}
}
public class C() {
private FooManager fooManager = new FooManager(); // (or inject, if you have IoC)
private BarManager barManager = new BarManager(); // (or inject, if you have IoC)
... etc
}
If you want to literally use the method code from A and B you can make your C class contain an instance of each. If you code against interfaces for A and B then your clients don't need to know you're giving them a C rather than an A or a B.
interface IA { void SomeMethodOnA(); }
interface IB { void SomeMethodOnB(); }
class A : IA { void SomeMethodOnA() { /* do something */ } }
class B : IB { void SomeMethodOnB() { /* do something */ } }
class C : IA, IB
{
private IA a = new A();
private IB b = new B();
void SomeMethodOnA() { a.SomeMethodOnA(); }
void SomeMethodOnB() { b.SomeMethodOnB(); }
}
Use composition:
class ClassC
{
public ClassA A { get; set; }
public ClassB B { get; set; }
public C (ClassA a, ClassB b)
{
this.A = a;
this.B = b;
}
}
Then you can call C.A.DoA(). You also can change the properties to an interface or abstract class, like public InterfaceA A or public AbstractClassA A.
Make two interfaces IA and IB:
public interface IA
{
public void methodA(int value);
}
public interface IB
{
public void methodB(int value);
}
Next make A implement IA and B implement IB.
public class A : IA
{
public int fooA { get; set; }
public void methodA(int value) { fooA = value; }
}
public class B : IB
{
public int fooB { get; set; }
public void methodB(int value) { fooB = value; }
}
Then implement your C class as follows:
public class C : IA, IB
{
private A _a;
private B _b;
public C(A _a, B _b)
{
this._a = _a;
this._b = _b;
}
public void methodA(int value) { _a.methodA(value); }
public void methodB(int value) { _b.methodB(value); }
}
Generally this is a poor design overall because you can have both A and B implement a method with the same name and variable types such as foo(int bar) and you will need to decide how to implement it, or if you just call foo(bar) on both _a and _b. As suggested elsewhere you should consider a .A and .B properties instead of combining the two classes.
You can define a base class for A and B where you can hold a common methods/properties/fields of those.
After implement C:Base.
Or in order to simulate multiple inheritance, define a common interface(s) and implement them in C
Hope this helps.
Do you mean you want Class C to be the base class for A & B in that case.
public abstract class C
{
public abstract void Method1();
public abstract void Method2();
}
public class A : C
{
public override void Method1()
{
throw new NotImplementedException();
}
public override void Method2()
{
throw new NotImplementedException();
}
}
public class B : C
{
public override void Method1()
{
throw new NotImplementedException();
}
public override void Method2()
{
throw new NotImplementedException();
}
}

Is there a way to initialize fields out of constructor in C#?

I seem to remember some kind of short hand way to initialize fields of a class sent to a constructor, something like:
Class A {
int n;
public A(int N) : n(N) {}
}
Any clues?
There is easy way to initialize class fields after constructor like this:
public class A
{
public int N;
public string S;
public A() {}
}
class B
{
void foo()
{
A a = new A() { N = 1, S = "string" }
}
}
That would be C++, but you tagged your question C#. C# has no notion of initialization lists, you simply assign your fields in the constructor. You can however chain constructors or call a base class constructor in a similar manner
// call base class constructor before your own executes
public class B : A
{
public B(int whatever)
: base(something)
{
// more code here
}
}
// call secondary constructor
public class B : A
{
private int _something;
public B() : this(10) { }
public B(int whatever)
{
_something = whatever;
}
}

Categories

Resources