I was recently working on a project where I needed to have the following functionality:
public interface IStart
{
public void StartStarting();
public bool IsDoneStarting();
}
public interface IEnd
{
public void StartEnding();
public bool IsDoneEnding();
}
These two interfaces basically do the same thing:
public interface IDo
{
public void StartDoing();
public bool IsDoneDoing();
}
Is there somehow a way to inherit IDo twice rather than IStart and IEnd individually? I highly doubt it, but it would certainly be convenient.
Another option to consider is using composition over inheritance. In a composition scenario, the IStart and IEnd implementations would be passed in to the .ctor, then accessed as properties.
Code is worth a thousand words...
public interface IDo
{
void StartDoing();
bool IsDoneDoing();
}
public interface IStart : IDo { }
public interface IEnd : IDo { }
public interface IWorker
{
IStart Start { get; }
IEnd End { get; }
}
public class Worker : IWorker
{
public IStart Start { get; }
public IEnd End { get; }
public Worker( IStart start, IEnd end )
{
Start = start;
End = end;
}
}
It can't be done to inherit one interface to the next. If you want a commonality expressed as such, I suggest using an abstract class which pulls in both interfaces and expresses that syntactic sugar you seek as such:
public abstract class IDo : IStart, IEnd
{
public void StartDoing() { StartStarting(); }
public bool IsDoneDoing() { return IsDoneEnding() }
public virtual void StartStarting() {}
public virtual bool IsDoneStarting() { return false; } // Override me.
public virtual void StartEnding() { }
public virtual bool IsDoneEnding() { return false; } // Override me.
}
Related
I'm new to C#, and I would really like to implement specific different methods for each subtype of a defined abstract class, but I am having trouble figuring out how to get the compiler to do this properly. For example:
public abstract class MasterClass { }
public class SubClass1 : MasterClass { }
public class SubClass2 : MasterClass { }
public class SeparateClass
{
public void HandleMasterClass(MasterClass item)
{
/*
stuff generic to both subclasses...
*/
SpecificMethod(item)
}
public void SpecificMethod(SubClass1 item)
{
//something specific to SubClass1
}
public void SpecificMethod(SubClass2 item)
{
//something specific to SubClass2
}
}
This returns an error in compiling because there is no SpecificMethod(MasterClass item), but what I really want is for it to choose the right method based on the subclass without having to write separate HandleMasterClass(SubClass1 item) and HandleMasterClass(SubClass2 item) methods because they are mostly the same code
my main language is Jula so I'm very used to relying on multiple dispatch and doing this kind of thing. I know its probably not idiomatic in C#, so how would I do this better?
EDIT: showing that the methods are not free but part of a separate class
here's a better concrete example
public abstract class MasterClass { public abstract int Stuff(); }
public class SubClass1 : MasterClass
{
public override int Stuff() { /*calculate and return an int*/ }
}
public class SubClass2 : MasterClass
{
public override int Stuff() { /*calculate and return an int*/ }
}
public class MasterClassDictionary
{
public Dictionary<int, SubClass1> subClass1Dict{get;} = new Dictionary<int, SubClass1>()
public Dictionary<int, SubClass2> subClass2Dict{get;} = new Dictionary<int, SubClass2>()
public void Add(MasterClass item)
{
int val = item.Stuff();
AddToDict(val, item);
}
void AddToDict(int val, SubClass1 item) { subClass1Dict[val] = item; }
void AddToDict(int val, SubClass2 item) { subClass2Dict[val] = item; }
}
I know this is a bit of a contrived example, but its similar to what I'm trying to do.
Generally, you want to put code specific to a class inside that class. So your abstract class would define the specific method signature, using the abstract keyword, and the implementation would live inside the class, using the override keyword, like this:
public abstract class MasterClass {
public abstract void SpecificMethod();
}
public class SubClass1 : MasterClass {
public override void SpecificMethod()
{
//something specific to SubClass1
// use the this keyword to access the instance
}
}
public class SubClass2 : MasterClass {
public override void SpecificMethod()
{
//something specific to SubClass2
// use the this keyword to access the instance
}
}
public class SeparateClass
{
public void HandleMasterClass(MasterClass item)
{
/*
stuff generic to both subclasses...
*/
item.SpecificMethod()
}
}
Per your comment, this is how I might implement the thing in your concrete example, though it may not meet your requirements:
public class MasterClassDictionary
{
public Dictionary<int, SubClass1> subClass1Dict{get;} = new Dictionary<int, SubClass1>()
public Dictionary<int, SubClass2> subClass2Dict{get;} = new Dictionary<int, SubClass2>()
public void Add(MasterClass item)
{
int val = item.Stuff();
if (item is SubClass1)
{
subClass1Dict[val] = item;
}
if (item is SubClass2)
{
subClass2Dict[val] = item;
}
}
}
The standard design pattern for this situation is the Visitor pattern. This is a somewhat complicated pattern, but the basic idea is that the subclasses know what type they are so we are going to call over to them via an virtual method called "Accept" and they will pass themselves back as a reference. The method they call back is called Visit and is overloaded for all the possible subclasses. Here is an implementation for your example:
public abstract class MasterClass
{
public abstract int Stuff();
// New method that all subclasses will have to implement.
// You could also have this be virtual with an implementation
// for Visit(MasterClass) to provider a default behavior.
public abstract void Accept(IVisitor visitor);
}
public class SubClass1 : MasterClass
{
public override int Stuff() => 0;
// We must override this even though its the "same" code in both subclasses
// because 'this' is a reference to a different type.
public override void Accept(IVisitor visitor) => visitor.Visit(this);
}
public class SubClass2 : MasterClass
{
public override int Stuff() => 1;
// We must override this even though its the "same" code in both subclasses
// because 'this' is a reference to a different type.
public override void Accept(IVisitor visitor) => visitor.Visit(this);
}
public interface IVisitor
{
// Need an overload for all subclasses.
void Visit(SubClass1 item);
void Visit(SubClass2 item);
}
public class MasterClassDictionary
{
public Dictionary<SubClass1, int> subClass1Dict { get; } = new Dictionary<SubClass1, int>();
public Dictionary<SubClass2, int> subClass2Dict { get; } = new Dictionary<SubClass2, int>();
public void Add(MasterClass item)
{
int val = item.Stuff();
var visitor = new Visitor(this, val);
item.Accept(visitor);
}
void AddToDict(SubClass1 item, int val) { subClass1Dict[item] = val; }
void AddToDict(SubClass2 item, int val) { subClass2Dict[item] = val; }
// Provides the visitor implementation that holds any state that might
// be needed and dispatches to the appropriate method.
private class Visitor : IVisitor
{
private MasterClassDictionary _parent;
private int _value;
public Visitor(MasterClassDictionary parent, int val)
{
_parent = parent;
_value = val;
}
public void Visit(SubClass1 item) => _parent.AddToDict(item, _value);
public void Visit(SubClass2 item) => _parent.AddToDict(item, _value);
}
}
That said, C# has added pattern matching with switch that would look substantially simpler. It's only downside is that it is doing more type checks which might be slower if this is in some really performance sensitive code, but is certainly going to be faster than using dynamic:
public void Add(MasterClass item)
{
int val = item.Stuff();
switch (item)
{
case SubClass1 i: AddToDict(i, val); break;
case SubClass2 i: AddToDict(i, val); break;
}
}
I'm working on a framework right now and the motto is "no redundancy" and "I don't want to know the vendor specifics" so most things are handled through Interfaces and Generic classes. Now I had the situation where I have an abstract class that wants to match things depending on it's own Enum variable se but it shouldn't have to know how the vendor provides a relatable variable to be matched to se. The vendor could have decided an integer, an Enum or a string would be the best to save that information but honestly I don't want to know.
So I thought well no problem have an abstract static method that must be provided by every implementation of a wrapper to compare se with the vendor specific way of saving that information.
//The original version I wanted to be possible
public abstract class AbstractGenericClass<TWrapper<T>, T> where TWrapper : AbstractGenericWrapper<T> {
protected TWrapper tWrapper;
//our SomeEnum se is somehow relatable to every T
//but we don't want to know how
protected SomeEnum se = ...;
//called on Start
public void Start() {
List<T> ts = FindObjectsOfType<T>;
foreach (T t in ts) {
if(T.Compare(t, this.se)) {
tWrapper = new TWrapper(t);
}
}
}
}
public abstract class AbstractGenericWrapper<T> {
T _t;
public AbstractGenericWrapper(T t) {
_t = t;
}
public static abstract bool Compare(T t, SomeEnum someEnum);
}
public class ConcreteNongenericWrapper : AbstractGenericWrapper<VendorSpecificImplementation> {
public static bool Compare(VendorSpecificImplementation t, SomeEnum someEnum) {
return t.vendorVariable.toLower().Equals(Enum.GetValues(typeof(someEnum), someEnum));
}
}
public class OtherConcreteNongenericWrapper : AbstractGenericWrapper<OtherVendorSpecificImplementation> {
public static bool Compare(OtherVendorSpecificImplementation t, SomeEnum someEnum) {
return t.otherVendorVariable % 3 == (int) someEnum;
}
}
public class SomeImplementation {
public static void main() {
AbstractGenericClass<ConcreteNongenericWrapper<ConcreteNongeneric>, ConcreteNongeneric> foo
= new AbstractGenericClass<ConcreteNongenericWrapper<ConcreteNongeneric>, ConcreteNongeneric>();
AbstractGenericClass<OtherConcreteNongenericWrapper<OtherConcreteNongeneric>, OtherConcreteNongeneric> bar
= new AbstractGenericClass<OtherConcreteNongenericWrapper<OtherConcreteNongeneric>, OtherConcreteNongeneric>();
foo.Start();
bar.Start();
}
}
I found out that that isn't possible and I wanted to know if this version down below is the best/only way of doing it? It has redundancy and I don't like it and it is longer.
//An attempt at a solution:
public abstract class AbstractGenericClass<TWrapper<T>, T> where TWrapper : AbstractGenericWrapper<T> {
protected TWrapper tWrapper;
//our SomeEnum se is somehow relatable to every T
//but we don't want to know how
protected SomeEnum se = ...;
//called on start
public abstract void Start();
}
public abstract class AbstractGenericWrapper<T> {
T _t;
public AbstractGenericWrapper(T t) {
_t = t;
}
}
public class ConcreteNongenericClass : AbstractGenericClass<VendorSpecificImplementation> {
//called on start
public override void Start() {
List<VendorSpecificImplementation> ts = FindObjectsOfType<VendorSpecificImplementation>;
foreach (VendorSpecificImplementation t in ts) {
if(t.vendorVariable.toLower().Equals(Enum.GetValues(typeof(someEnum), someEnum))) {
tWrapper = new ConcreteNongenericWrapper(t);
}
}
}
}
public class ConcreteNongenericWrapper : AbstractGenericWrapper<VendorSpecificImplementation> {
}
public class OtherConcreteNongenericClass : AbstractGenericClass<OtherVendorSpecificImplementation> {
//called on start
public void Start() {
List<OtherVendorSpecificImplementation> ts = FindObjectsOfType<OtherVendorSpecificImplementation>;
foreach (OtherVendorSpecificImplementation t in ts) {
if(t.otherVendorVariable % 3 == (int) someEnum) {
tWrapper = new OtherConcreteNongenericWrapper(t);
}
}
}
}
public class OtherConcreteNongenericWrapper : AbstractGenericWrapper<OtherVendorSpecificImplementation> {
}
public class SomeImplementation {
public static void main() {
AbstractGenericClass<ConcreteNongenericWrapper<ConcreteNongeneric>, ConcreteNongeneric> foo
= new AbstractGenericClass<ConcreteNongenericWrapper<ConcreteNongeneric>, ConcreteNongeneric>();
AbstractGenericClass<OtherConcreteNongenericWrapper<OtherConcreteNongeneric>, OtherConcreteNongeneric> bar
= new AbstractGenericClass<OtherConcreteNongenericWrapper<OtherConcreteNongeneric>, OtherConcreteNongeneric>();
foo.Start();
bar.Start();
}
}
Thank you very much for your time and help!
Obviously using virtual and override is the normal situation, but does this telecoms'ish example count?
public class Pipe
{
// whole bunch of protected member variables such as bandwidth, latency, download limit
// etc,
public int GetCost()
{
// work out cost based on above
}
}
public class BigFatPipe : Pipe
{
public BigFatPipe()
{
// sets up the member variables one way
}
}
public class CheapestPossiblePipe: Pipe
{
public CheapestPossiblePipe()
{
// sets up the member variables another way
}
}
then you might call
PrintPrice(new BigFatPipe())
PrintPrice(new CheapestPossiblePipe())
public void PrintPrice(Pipe pipe)
{
int a = pipe.GetCost();
....
}
You'll get two different answers. This isn't the most useful example but does it count?
This post here has a useful discussion of what exactly polymorphism is.
I think most definitions do not explicitly state that an object must have virtual functions to be polymorphic - so yes, I think your example counts.
Constructor overloading is a recognized method to implement static polymorphism. While this isn't really constructor overloading, it's close. So yes, I'd call it polymorphism.
This pattern does work, but introducing a bunch of classes will confuse the user uselessly: they will wonder what the classes do differently.
A few factories methods will do the same job and will be easier to understand and maintain:
public class Pipe
{
// whole bunch of private member variables such as bandwidth, latency, download limit
// etc,
public int GetCost()
{
// work out cost based on above
}
public static Pipe MakeBigFatPipe()
{
var result = new Pipe();
// sets up the member variables one way
return result;
}
public static Pipe MakeCheapestPossiblePipe()
{
var result = new Pipe();
// sets up the member variables another way
return result;
}
}
If I were you I would use folowing approach:
public interface IGetCost
{
int GetCost();
}
public class Pipe : IGetCost
{
public int GetCost(){}
}
public class BigFatPipe : IGetCost
{
//aggregation
private readonly Pipe _pipe;
public BigFatPipe(Pipe pipe)
{
_pipe = pipe;
}
public int GetCost() { }
}
public class CheapestPossiblePipe : IGetCost
{
private readonly Pipe _pipe;
public CheapestPossiblePipe(Pipe pipe)
{
_pipe = pipe;
}
public int GetCost() { }
}
public static void PrintPrice(IGetCost obj)
{
int cost = obj.GetCost();
Console.WriteLine(cost);
}
static void Main(string[] args)
{
IGetCost p;
p = new Pipe();
PrintPrice(p);
p = new BigFatPipe();
PrintPrice(p);
p = new CheapestPossiblePipe();
PrintPrice(p);
}
I also need to say that there're two different things - polymorphism and overloading
polymorphism
public class foo
{
public virtual void foo1{/*....*/}
}
public class fooA : foo
{
public override void foo1{/*....*/}
}
public class fooB : foo
{
public new void foo1{/*....*/}
}
public class fooC : foo
{
//new is the default modifier
public void foo1{/*....*/}
}
overloading
public class foo{
public int foo1{/*....*/}
public int foo1(int a){/*....*/}
public int foo1(string a){/*....*/}
public int foo1(int a, string b){/*....*/}
}
Why can't interfaces implement methods like this?
public interface ITargetableUnit {
//Returns whether the object of a class that implements this interface is targetable
bool unitCanBeTargeted(){
bool targetable = false;
if(this is Insect){
targetable = (this as Insect).isFasterThanLight();
}
else if(this is FighterJet){
targetable = !(this as FighterJet).Flying;
}
else if(this is Zombie){
targetable = !(this as Zombie).Invisible;
}
return targetable;
}
}
Insect, and Zombie all already derives from base class Creature, and FighterJet derives from class Machine However, not all Creature-s are targetable and do not use ITargetableUnit inteface.
Is there any workaround to solve the issue that I am facing?
Like everybody said you can't define behaviour for interfaces. Inherite the interface to the specific classes.
public interface ITargetableUnit
{
bool unitCanBeTargeted();
}
public class Insect : ITargetableUnit //you can add other interfaces here
{
public bool unitCanBeTarget()
{
return isFasterThanLight();
}
}
public class Ghost : ITargetableUnit
{
public bool unitCanBeTarget()
{
return !Flying();
}
}
public class Zombie : ItargetableUnit
{
public bool unitCanBeTarget()
{
return !Invisible();
}
}
Just for the record, you can actually do this (DONT!) but this isnt considered a good practice to make extensionmethods for code you have acces to. Mybirthname's solution is the way to go, this is just for demonstration.
public interface ITargetableUnit { }
public static class ITargetableUnitExtension
{
public static bool unitCanBeTargeted(this ITargetableUnit unit)
{
bool targetable = false;
Insect insect = unit as Insect;
if(insect != null)
return insect.isFasterThanLight();
FighterJet jet = unit as FighterJet;
if(jet != null)
return !jet.Flying;
Zombie zombie = unit as Zombie;
if(zombie != null)
return zombie.Invisible;
return false;
}
}
Maybe you want an abstract class and not an interface?
Interfaces define what methods a class provides. Abstract classes do this as well but can also take over some calculations for every child.
Please be aware that from a technical perspective an Insect can also be a Zombie.
Happy coding!
public abstract class TargetableUnit
{
//Returns whether the object of a class that implements this interface is targetable
public bool unitCanBeTargeted()
{
bool targetable = false;
if (this is Insect)
{
targetable = (this as Insect).isFasterThanLight();
}
else if (this is FighterJet)
{
targetable = !(this as FighterJet).Flying;
}
else if (this is Zombie)
{
targetable = !(this as Zombie).Invisible;
}
return targetable;
}
}
public class Insect : TargetableUnit
{
public bool isFasterThanLight()
{
return System.DateTime.UtcNow.Second == 0;
}
}
public class FighterJet : TargetableUnit
{
public bool Flying { get; set; }
}
public class Zombie : TargetableUnit
{
public bool Invisible { get; set; }
}
Suppose that we would like to separate out the read and write access in an interface pattern as below.
namespace accesspattern
{
namespace ReadOnly
{
public interface IA { double get_a(); }
}
namespace Writable
{
public interface IA : ReadOnly.IA { void set_a(double value); }
}
}
This is easy to implement:
namespace accesspattern
{
namespace ReadOnly
{
public class A : IA
{
protected double a;
public double get_a() { return a; }
}
}
namespace Writable
{
public class A : ReadOnly.A, IA
{
public void set_a(double value) { base.a = value; }
}
}
}
Suppose that we need another class which inherits from A and so we go ahead and define an interface for it:
namespace accesspattern
{
namespace ReadOnly
{
public interface IB : ReadOnly.IA { int get_b(); }
}
namespace Writable
{
public interface IB : ReadOnly.IB, Writable.IA { void set_b(int value); }
}
}
Implementing this is not so easy. One always feels that Writable.B should inherit from two base classes, Writable.A and ReadOnly.B, to avoid repeated code.
Is there a recommended Design Pattern to use? The aim is to be able to return "read access only" and "read write access" objects separately (decided at compile time) depending on requirements. It would be nice if the solution pattern makes it easy to add more layers of inheritance, classes C, D...
I know that the issue of Multiple Inheritance crops up here and that it has been discussed at length elsewhere in many, many, places. But my question is not so much "How to implement the interfaces which are defined inside the namespace accesspattern without using multiple inheritance" (although I would like to learn the best way to do that) but rather, how can we define the ReadOnly/Writable versions of a class separately and also support inheritance without it getting very, very, messy?
For what it is worth here is one (messy) solution [see below for much a better implementation]:
namespace accesspattern
{
namespace ReadOnly
{
public class A : IA
{
protected double a;
public double get_a() { return a; }
}
public class B : IB
{
protected int b;
public int get_b() { return b; }
}
}
namespace Writable
{
public class A : ReadOnly.A, IA
{
public void set_a(double value) { base.a = value; }
}
public class B : ReadOnly.B, IB
{
private IA aObj;
public double get_a() { return aObj.get_a(); }
public void set_a(double value) { aObj.set_a(value); }
public void set_b(int value) { base.b = value; }
public B() { aObj = new A(); }
}
}
}
}
Update: I think that this (below) is what Eugene is talking about. This implementation pattern is pretty good, I think. By only passing around "writeProtected" views of classes one can implement algorithms which require that the state of the class will not change and only use "writeEnabled" views where it is meant that the function will/could cause a change in state avoiding.
namespace access
{
// usual usage is at least readable
public interface IA { double get_a(); }
public interface IB : IA { int get_b(); }
// special usage is writable as well
namespace writable
{
public interface IA : access.IA { void set_a(double value); }
public interface IB : access.IB, IA { void set_b(int value);}
}
// Implement the whole of A in one place
public class A : writable.IA
{
private double a;
public double get_a() { return a; }
public void set_a(double value) { a = value; }
public A() { }
//support write-protection
public static IA writeProtected() { return new A(); }
public static writable.IA writable() { return new A(); }
}
// implement the whole of B in one place and now no issue with using A as a base class
public class B : A, writable.IB
{
private int b;
public double get_b() { return b; }
public void set_b(int value) { b = value; }
public B() : base() { }
// support write protection
public static IB writeProtected() { return new B(); }
public static writable.IB writable() { return new B(); }
}
public static class Test
{
static void doSomething(IA a)
{
// a is read-only
}
static void alterState(writable.IB b)
{
// b is writable
}
static void example()
{
// Write protected
IA a = access.A.writeProtected();
IB b = access.B.writeProtected();
// write enabled
writable.IA A = access.A.writable();
writable.IB B = access.B.writable();
Console.WriteLine(a.get_a());
B.set_b(68);
doSomething(A); // passed as writeprotected
alterState(B); // passed as writable
}
}
}
I know this thread is one year old, but I'm wondering if it would make sense to have something like this:
interface ReadOnlyA
{
object A { get; }
}
interface WriteableA : ReadOnlyA
{
new object A {get; set;}
}
You can provide the read/write access at Service level and not at Entity level. In that case you can code generate a wrapper around services that handles the read/write access.
Patterns used: Decorator, Dependency Injection