Avoid numerous casts in inheritance tree - c#

This is a problem which seems super basic but I still can't find a way to clear it. When I have a simple inheritance like B and C inheriting from A
A
|
|-----|
B C
Let's say these are interface like:
public interface A
{
List<A> Children { get; }
}
My issue: When I got through B.Children I have to cast it to B every time I want to use its specifics. Is there a way to have a list of children without having to declare the children in the leaves of the inheritance tree?
Precision: A child is always of the same type as its parent (or sub-type). And the tree can go deeper. As an example, think about a UI system with objects, containers, controls, labels where a class has as children only things of the same type or sub-types of itself.
Here is my code. I have the top level as
public interface ITerm
{
String text { get; }
}
Then, as offered by #Damien_The_Unbeliever
public interface ITerm<T> : ITerm where T : ITerm
{
List<T> Children { get; }
}
public interface ITermControl : ITerm<ITermControl> { ... }
public class TermControl : ITermControl { ... }
I am starting to think it is useless to have access to a List<ITerm> ITerm.Children as well as List<ITermControl> ITermControl.Children. That's what I was trying to explain.
Thanks

You might try doing this:
public interface A<T> where T: A<T> {
List<T> Children {get;}
}
Which Eric Lippert describes in his article Curiouser and Curiouser:
This is a C# variation on what's called the Curiously Recurring Template Pattern in C++, and I will leave it to my betters to explain its uses in that language. Essentially the pattern in C# is an attempt to enforce the usage of the CRTP.
And points out that it doesn't really enforce correct types throughout - so at best, it's a form of documentation rather than something that prevents bad things from happening.

Related

Dealing with mirrored inheritance trees

Quite often I find myself dealing with a pattern similar to this one
Two inheritance trees, where there is some kind of mirroring. Each of the subclasses in the left tree has a different subclass in the right tree as source
The MappingEnd class:
public class MappingEnd
{
public NamedElement source { get; set; }
}
The question is, how to deal with that in the subclasses. Do I hide the parent source property using the new keyword?
public class AssociationMappingEnd:MappingEnd
{
public new Association source { get; set; }
}
Or do I simply provide a second property casting the NamedElement to Association ?
public class AssociationMappingEnd:MappingEnd
{
public Association associationSource
{
get
{
return (Association)this.source;
}
set
{
this.source = value;
}
}
}
Why would I choose one over the other. Or is there a better way to implement this type of pattern?
In the first design, public new Association source can easily cause trouble. You can still access the hidden member public NamedElement source accidentally. which is not cool.
For example, look at this pseudo-code:
IEnumerable<MappingEnd> MyMixedCollection = all kinds of MappingEnd objects
((AssociationMappingEnd)MyMixedCollection.First()).source //is cool
MyMixedCollection.First().source //access the hidden member, not cool
The new keyword is not the best design practice because it doesn't hide the inherited member. What it does is basically hiding the warning message that comes without it.
I personally never consider this as a valid design.
The second design is much more reliable because these names never get mixed up
AssociationMappingEnd.associationSource is Association
AssociationMappingEnd.source is NamedElement
MappingEnd.source is NamedElement
However, it can get confusing since these source and associationSource are actually the same. It works, but it can be better.
We can't use override on source and give it a new type, we could use public virtual NamedElement source, but then we would lost type-safety. To retain type-safety we can use Generics, as elgonzo suggested.
The left side needs to be generic, because it depends on the types of its right side classes, so we should start with the top class on the left side:
public class MappingEnd<T> where T : NamedElement
{
public T source { get; set; }
}
Now you can have either or both of these classes:
public class AssociationMappingEnd<T> : MappingEnd<T> where T : Association
{
}
public class AssociationMappingEnd : MappingEnd<Association>
{
}
Now you got only one source with a safe type:
AssociationMappingEnd<Association>.source is Association
AssociationMappingEnd.source is Association
MappingEnd<NamedElement>.source is NamedElement
MappingEnd<Association>.source is Association

How can I access a Child class's interface property when that child is stored in a list as its Parent?

I think the title of this post might not explain my issue very well, so here is some code that should hopefully explain it a little better:
interface IFoo {
IFoo Bar {get; set;}
}
class Parent {
}
class Child1 : Parent, IFoo {
}
class Child2 : Parent, IFoo {
}
class Manager {
List<Parent> Parents = new List<Parent>();
Parents.Add(new Child1());
Parents.Add(new Child2());
// I want to do something like this:
Parents[0].Bar = Parents[1];
}
I believe (Parents[0] is IFoo) will evaluate as true, and yet I can't use Parents[0].Bar because Parent does not contain a definition for Bar. Can you explain why this is? Also, how can I effectively do the same thing that (at least in my head) Parents[0].Bar = Parents[1] should do?
Hopefully this makes sense. I'll try to clarify things if needed. Thanks in advance for taking a look!
Use type casting:
((IFoo)Parents[0]).Bar
But actually it is bad design in your case if you depend on inplementation.
If you want to do the assignment, you need to let your code have the same information that you have yourself, and also the same information that the Manager class has.
That means that you must tell the class Parent that it knows about IFoo, and that means:
abstract class Parent : IFoo
{
public abstract IFoo Bar { get; set; }
}
It now also states that you can't instantiate a Parent alone. From your comments, it seems to make sense (you saying Parent should have no implementation of Bar, only know about it). If that makes sense it is abstract, but if not remove the abstract and add the implementation of Bar to Parent, or if your real implementation differs for each child, make it virtual.

How to deal with Lack of Multiple Inheritance in C#

I am working on a mini-framework for "runnable" things. (They are experiments, tests, tasks, etc.)
// Something that "runs" (in some coordinated way) multiple "runnable" things.
interface IRunnableOf<T> where : IRunnable
// Provide base-class functionality for a "runner"
abstract class RunnerBase<T> : IRunnableOf<T>
class SequentialRunner<T> : RunnerBase<T> // Same interface, different behavior.
class ConcurrentRunner<T> : RunnerBase<T>
// other types of runners.
class ConcurrentBlockRunner : SequentialRunner<Block>
class SequentialBlockRunner : ConcurrentRunner<Block>
Now, how can I reconcile ConcurrentBlockRunner and SequentialBlockRunner? By this I mean:
Refer to them by a common ancestor, for use in a collection. (IEnuerable<T> where T = ??)
Provide additional base class functionality. (Add a property, for example).
I remedied #1 by adding another interface that just specified a type parameter to IA<T>:
interface IBlockRunner : IRunnableOf<Block> { }
And modified my ConcurrentBlockRunner and SequentialBlockRunner definitions to be:
class ConcurrentBlockRunner : SequentialRunner<Block>, IBlockRunner
class SequentialBlockRunner : ConcurrentRunner<Block>, IBlockRunner
Since ConcurrentBlockRunner and SequentialBlockRunner both use Block for their type parameter, this seems to be a correct solution. However, I can't help but feel "weird" about it, because well, I just tacked that interface on.
For #2, I want to add a couple pieces of common data to ConcurrentBlockRunner and SequentialBlockRunner. There are several properties that apply to them, but not to their only common base class, which is all the way up at RunnerBase<T>.
This is the first time while using C# that I've felt multiple inheritance would help. If I could do:
abstract class BlockRunnerBase {
int Prop1 { get; set; }
int Prop2 { get; set; }
class ConcurrentBlockRunner : SequentialRunner<Block>, BlockRunnerBase
class SequentialBlockRunner : ConcurrentRunner<Block>, BlockRunnerBase
Then I could simply add these extra properties to BlockRunnerBase, and everything would just work. Is there a better way?
I know I will be recommended immediately to consider composition, which I began to work with:
class BlockRunner : IBlockRunner {
IBlockRunner _member;
int Prop1 { get; set; } // Wish I could put these in some base class
int Prop2 { get; set; }
// Lots of proxy calls, and proxy events into _member
void Method() { _member.Method(); }
event SomeEvent
{
add { _member.SomeEvent += value; }
remove { _member.SomeEvent -= value; }
}
}
The problem I encountered (driving me to write this question) was that once you compose, you lose type compatibility. In my case, _member was firing an event, so the sender parameter was of type SequentialBlockRunner. However, the event handler was trying to cast it to type BlockRunner, which of course failed. The solution there is not use add/remove to proxy the events, but actually handle them, and raise an event of my own. So much work just to add a couple properties...
Composition over Inheritance, FTW!
To be more explicit:
class SequentialRunner<T> : RunnerBase<T>
should implement IRunnableOf<T> and proxy the RunnerBase<T> without inheriting it.
class SequentialRunner<T> : IRunnableOf<T>
{
private readonly RunnerBase<T> _runnerBase;
...
}
You can use extension methods to create mixin-like constructs, even with property-like elements.
I've also created an experiment with trait-like constructs in C#, NRoles.
But, all of these require non-standard coding, and will not be ideal for APIs that are meant to be exposed to third parties. I think you should try to rearrange your classes and use composition with delegation using interfaces if possible.

What design pattern to use when I want only some derived classes to have access to a method in base class?

I have a unique problem/situation here. Trying to make it as simple as possible. I have a base class (say Parent) and a whole bunch of derived classes (say Child1, Child2 ..ChildN) directly deriving from the base class (Parent). I want to change the base class and add a "AVeryPrivilegedMethod" which will only be accessible to Child2 and Child3 and not to any other Children (or make it configurable such that in future Child5 can also use it in future, with minimal changes). What design pattern /Architectural pattern will fit this bill?
Language used - C#.
PS: I was thinking about using InternalVisibleTo but realize that this gets applied at the assembly level
It sounds as though you're missing another abstract class (SpecialChild for want of a better name) that inherits from Parent but from which Child2 and Child3 are derived.
Parent
|
|------------------|------------|----------|
Child1 SpecialChild Child4 Child5
|
|---------------------|
Child2 Child3
Ask yourself this question: what is different about Child2 and Child3 such that they share common behaviour themselves, but have different behaviour to all of the other children? SpecialChild models that behaviour and in the example you gave in your question would be the place to implement AVeryPrivilegedMethod.
I don't see what this has to do with "design patterns" -- it's just a matter of language features. C# does not have a language feature that permits this sort of pick-and-choose encapsulation easily.
I guess your options are to either insert a new class in the hierarchy, BaseWithExtras, deriving from Base, and have some children derive from Base and others from BaseWithExtras, or to stop worrying about it and just make the method available to all derived classes.
You would want to make another level of abstraction:
public class Parent { }
public class MethodContainer : Parent { public void SomeMethod() { } }
Then each child class inherits the appropriate class:
// Does not have method
public class ChildA : Parent
// Has Method
public class ChildB: MethodContainer
If you only have access to the base class, I'd say to use reflection on the type of the class in the base method, and only allow classes that you want to correctly use the base method. If that's not the case, and you have an ability to modify the hierarchy or the derived classes, just make another class derived from your base that exposes your method of interest, and make your classes derive from that.
There are probably no good options, since this isn't a standard level of protection. Here's one option
class Parent
{
private void AVeryPrivilegedMethod() {}
public static void AVeryPrivilegedMethod(Child2 c) { ((Parent)c).AVeryPrivilegedMethod(); }
public static void AVeryPrivilegedMethod(Child3 c) { ((Parent)c).AVeryPrivilegedMethod(); }
}
Later, you call it like this:
Child2 c = new Child2();
Parent.AVeryPrivilegedMethod(c);
This is assuming that you want compiler checking (not using reflection at runtime to check Child2 and Child3), and for some reason need the hierarchy you stated. There are other answers that suggest a new level of subclass, which may be the best answer in your situation. If not, this might help.
How about good old association with Dependency Injection (so you can change it later if needed to allow other classes to access the functions).
public class Parent {
private PrivilegedFunctions p;
public Parent(PrivilegedFunctions inP) { p = inP; }
}
public interface PrivilegedFunctions {
void SomeFuncHere();
}
public class AllowPrivileges : PrivilegedFunctions {
public void AllowPrivileges () { }
public void SomeFuncHere()
{
// Actual implementation
}
}
public class NoPrivileges : PrivilegedFunctions {
public void NoPrivileges () { }
public void SomeFuncHere()
{
// No implementation
}
}
public class Child1 : Parent {
public Child1(PrivilegedFunctions inP) : base(inP) { }
}
Then depending on the Child, you can inject the AllowPrivileges or NoPrivileges version.
// Child with privileges
Child1 with_priv = new Child1(new AllowPrivileges());
with_priv.SomeFuncHere(); // Does privileged operation
// Child without privileges
Child1 without_priv = new Child1(new NoPrivileges());
without_priv.SomeFuncHere(); // Does nothing
If those methods are going to be used in only certain child classes including them in the inheritance hierarchy doesnt look like a good idea . Here what we want to achieve is implementation reuse so composition through dependency injection would be a good idea, however if you need to expose that method as a part of your classes interface then Mixin(if it was possible in C#) would have been the thing to go for.

Why cast to an interface?

In Jesse Liberty's Programming C# (p.142) he provides an example where he casts an object to an interface.
interface IStorable
{
...
}
public class Document : IStorable
{
...
}
...
IStorable isDoc = (IStorable) doc;
...
What is the point of this, particularly if the object's class implements the inteface anyway?
EDIT1: To clarify, I'm interested in the reason for the cast (if any), not the reason for implementing interfaces. Also, the book is his 2001 First Edition (based on C#1 so the example may not be germane for later versions of C#).
EDIT2: I added some context to the code
Because you want to restrict yourself to only methods provided by the interface. If you use the class, you run the risk of calling a method (inadvertently) that's not part of the interface.
There is only one reason when you actually need a cast: When doc is of a base type of an actual object that implements IStorable. Let me explain:
public class DocBase
{
public virtual void DoSomething()
{
}
}
public class Document : DocBase, IStorable
{
public override void DoSomething()
{
// Some implementation
base.DoSomething();
}
#region IStorable Members
public void Store()
{
// Implement this one aswell..
throw new NotImplementedException();
}
#endregion
}
public class Program
{
static void Main()
{
DocBase doc = new Document();
// Now you will need a cast to reach IStorable members
IStorable storable = (IStorable)doc;
}
}
public interface IStorable
{
void Store();
}
If the object implements the interface explicitly (public void IStorable.StoreThis(...)) that casting is the easiest way to actually reach the interface members.
I am not sure under what context the example was given in the book. But, you generally can type cast an object to interface to achieve multiple inheritance. I have given the example below.
public interface IFoo
{
void Display();
}
public interface IBar
{
void Display();
}
public class MyClass : IFoo, IBar
{
void IBar.Display()
{
Console.WriteLine("IBar implementation");
}
void IFoo.Display()
{
Console.WriteLine("IFoo implementation");
}
}
public static void Main()
{
MyClass c = new MyClass();
IBar b = c as IBar;
IFoo f = c as IFoo;
b.Display();
f.Display();
Console.ReadLine();
}
This would display
IBar implementation
IFoo implementation
It's pretty hard to tell without more of the context. If the variable doc is declared to be a type which implements the interface, then the cast is redundant.
Which version of the book are you reading? If it's "Programming C# 3.0" I'll have a look tonight when I'm at home.
EDIT: As we've seen in the answers so far, there are three potential questions here:
Why cast in the statement shown in the question? (Answer: you don't have to if doc is of an appropriate compile-time type)
Why is it ever appropriate to explicitly cast to an implemented interface or base class? (Answer: explicit interface implementation as shown in another answer, and also for the sake of picking a less specific overload when passing the cast value as an argument.)
Why use the interface at all? (Answer: working with the interface type means you're less susceptible to changes in the concrete type later on.)
The doc object might be of a type that implements members of IStorable explicitly, not adding them to the classes primary interface (i.e., they can only be called via the interface).
Actually "casting" (using the (T) syntax) does not make any sense since C# handles upcasts (cast to parent type) automatically (unlike F# for instance).
There are a lot of good answers here, but I don't really think they answer WHY you actually WANT to use the most restrictive interface possible.
The reasons do not involve your initial coding, they involve the next time you visit or refactor the code--or when someone else does it.
Let's say you want a button and are placing it on your screen. You are getting the button either passed in or from another function, like this:
Button x=otherObject.getVisibleThingy();
frame.add(x);
You happen to know that VisibleThingy is a button, it returns a button, so everything is cool here (no cast required).
Now, lets say that you refactor VisibleThingy to return a toggle button instead. You now have to refactor your method because you knew too much about the implementation.
Since you only NEED the methods in Component (a parent of both button and Toggle, which could have been an interface--same thing pretty much for our purposes), if you had written that first line like this:
Component x=(Component)otherObject.getVisibleThingy();
You wouldn't have had to refactor anything--it would have just worked.
This is a very simple case, but it can be much more complex.
So I guess the summary would be that an interface is a specific way to "View" your object--like looking at it through a filter...you can only see some parts. If you can restrict your view enough, the object can "Morph" behind your particular view and not effect anything in your current world--a very powerful trick of abstraction.
The best reason why you would cast to interfaces would be if you are writing code against objects and you don't know what concrete type they are and you don't want to.
If you know that you might come across an object that implements a specific interface you could then get the values out of the object without having to know the concrete class that this object is. Also, if you know that an object implements a given interface, that interface might define methods that you can execute to take certain actions on the object.
Here's a simple example:
public interface IText
{
string Text { get; }
}
public interface ISuperDooper
{
string WhyAmISuperDooper { get; }
}
public class Control
{
public int ID { get; set; }
}
public class TextControl : Control, IText
{
public string Text { get; set; }
}
public class AnotherTextControl : Control, IText
{
public string Text { get; set; }
}
public class SuperDooperControl : Control, ISuperDooper
{
public string WhyAmISuperDooper { get; set; }
}
public class TestProgram
{
static void Main(string[] args)
{
List<Control> controls = new List<Control>
{
new TextControl
{
ID = 1,
Text = "I'm a text control"
},
new AnotherTextControl
{
ID = 2,
Text = "I'm another text control"
},
new SuperDooperControl
{
ID = 3,
WhyAmISuperDooper = "Just Because"
}
};
DoSomething(controls);
}
static void DoSomething(List<Control> controls)
{
foreach(Control control in controls)
{
// write out the ID of the control
Console.WriteLine("ID: {0}", control.ID);
// if this control is a Text control, get the text value from it.
if (control is IText)
Console.WriteLine("Text: {0}", ((IText)control).Text);
// if this control is a SuperDooperControl control, get why
if (control is ISuperDooper)
Console.WriteLine("Text: {0}",
((ISuperDooper)control).WhyAmISuperDooper);
}
}
}
running this little program would give you the following output:
ID: 1
Text: I'm a text control
ID: 2
Text: I'm another text control
ID: 3
Text: Just Because
Notice that I didn't have to write any code in the DoSomething method that required me to know anything about all the objects I was working on being concrete object types. The only thing that I know is that I'm working on objects that are at least an instance of the Control class. I can then use the interface to find out what else they might have.
There's a million different reasons that you would take this approach with interfaces on your objects but it gives you a loose way to access your objects without having to know exactly what it is.
Think of all the credit cards in the world, every company makes their own, the interface is the same though, so every card reader can have a card swiped through it that follows the standard. Similar to the usage of interfaces.
As has been noted, the casting is superfluous and not necessary. However, it is a more explicit form of coding which would be useful to beginners in aiding their understanding.
In an introductory textbook, it is best to explicitly act, rather than let the compliler do things implicitly, which would be more confusing for beginners.
The "doc" is not of type "IStorable" so it would be confusing for beginners to see that it is being assigned to a isDoc. By explicitly casting, the author (of the book and of the code) is saying that a document can be casted to an IStorable object, but it is NOT THE SAME as an IStorable object.
The point is, the object (where did you get it?) may not implement the interface, in which case an exception is thrown which can be caught and dealt with. Of course you can use the "is" operator to check, and the "as" operator to cast instead of the C-style cast.
To allow for the most decoupling between pieces of code...
See the following article for more:
Interfaces
The main reason you would explicitly cast to an interface is if the members of the interface are implemented explicitly (i.e. with fully-qualified names in the form of InterfaceName.InterfaceMemberName). This is because when you fully-qualify them with the interface name, those members are not actually part of the implementing class's API. You can only get to them via casting to the interface.
Here's an example you can run as-is:
using System;
public interface ISomethingDoer {
void DoSomething();
}
public class ThingA : ISomethingDoer {
public void DoSomething(){
Console.WriteLine("ThingA did it!");
}
}
public class ThingB : ISomethingDoer {
// This is implemented explicitly by fully-qualifying it with the interface name
// Note no 'scope' here (e.g. public, etc.)
void ISomethingDoer.DoSomething(){
Console.WriteLine("ThingB did it!");
}
}
public static class Runner {
public static void Main(){
var a = new ThingA();
a.DoSomething(); // Prints 'ThingA did it!'
var b = new ThingB();
b.DoSomething(); // NOTE: THIS WILL NOT COMPILE!!!
var bSomethingDoer = (ISomethingDoer)b;
bSomethingDoer.DoSomething(); // Prints 'ThingB did it!'
}
}
HTH!

Categories

Resources