Sorry for the vague title, but I wasn't sure how to summarize this in one phrase. I have a situation with a lot of redundant C# code, and it really looks like some kind of crafty trick using some property of inheritance or generics would solve this. However, I'm not a terribly experienced programmer (particularly with C#) and just can't quite see the solution.
The situation, in simplified form, looks something like this. I have a bunch of classes that all inherit from one type.
public class Foo : SuperFoo
{
...
public Foo SomeMethod() { ... }
}
public class Bar : SuperFoo
{
...
public Bar SomeMethod() { ... }
}
public class Baz : SuperFoo
{
...
public Baz SomeMethod() { ... }
}
...
public class SuperFoo
{
...
}
The problem comes when collections of these objects need to be processed. My first-draft solution (the bad one) looks like this:
public void SomeEventHasHappened(...)
{
ProcessFoos();
ProcessBars();
ProcessBazes();
...
}
public void ProcessFoos()
{
...
foreach (var foo in fooList)
{
...
foo.SomeMethod();
}
}
public void ProcessBars()
{
...
foreach (var bar in barList)
{
...
bar.SomeMethod();
}
}
...and so on. The problem is that basically all of the code in the ProcessX methods is the same, other than the type of the objects that are being operated on. It would be nice to consolidate all of these into one method for obvious reasons.
My first thought was to just make a generic Process() method that took a List<SuperFoo> as a parameter and just proceed from there. The problem is that a generic SuperFoo does not have a SomeMethod(), and it can't have one because each of the child classes' SomeMethod() has a different return type, so having overrides doesn't work.
I usually add an interface which operates on base types.
interface ISuperFoo
{
public ISuperFoo SomeMethod() { ... }
}
public class Foo : SuperFoo, ISuperFoo
{
// concrete implementation
public Foo SomeMethod() { ... }
// method for generic use, call by base type
public ISuperFoo ISuperFoo.SomeMethod()
{
return SomeMethod();
}
}
public void Processs()
{
...
foreach (var iSuperFoo in list)
{
...
iSuperFoo.SomeMethod();
}
}
Of course it depends what you are using the result for.
Sometimes you can make it easier using generics, but you also can end up in a mess. Sometimes it is just easier to downcast somewhere. Of course, you try to avoid this whenever you can afford it.
Here's an example of how this might work using generics and making SuperFoo an abstract class.
public interface ISuperFoo
{
...
}
public abstract class SuperFoo<T> where T : ISuperFoo
{
public abstract T SomeMethod();
}
public class BazReturn : ISuperFoo
{
...
}
public class Baz: SuperFoo<BazReturn>
{
public override BazReturn SomeMethod()
{
throw new NotImplementedException();
}
}
public class BarReturn : ISuperFoo
{
...
}
public class Bar : SuperFoo<BarReturn>
{
public override BarReturn SomeMethod()
{
throw new NotImplementedException();
}
}
public static class EventHandler
{
public static void SomeEventHasHappened(List<SuperFoo<ISuperFoo>> list)
{
foreach (SuperFoo<ISuperFoo> item in list)
{
ISuperFoo result = item.SomeMethod();
}
}
}
You could replace the ISuperFoo interface with a concrete class if needed, but then you would have to cast the return value which kind of defeats the purpose.
public abstract class SuperFoo<T>
{
public abstract T SomeMethod();
}
public class Foo : SuperFoo<int>
{
public override int SomeMethod()
{
throw new NotImplementedException();
}
}
public static class EventHandler
{
public static void SomeEventHasHappened(List<SuperFoo<int>> list)
{
foreach (SuperFoo<int> item in list)
{
item.SomeMethod();
}
}
}
Related
i'm trying to build a sort of framework for some base process in an app. There is some common behavior where i have to execute some operations but these operations are different depending on some scenarios. I have done something i'm not sure if it's considered a bad practice to make something like this:
public interface IMyDto
{
string makerIdentifier { get; set; }
}
public class DtoOne:IMyDto
{
public string makerIdentifier { get; set; }
//Custom properties for ConcreteOne
}
public class DtoTwo:IMyDto
{
public string makerIdentifier { get; set; }
//Custom properties for ConcreteTwo
}
public abstract class AbstractMaker
{
public abstract void DoSomething(IMyDto myInterface);
}
public class ConcreteMakerOne:AbstractMaker
{
public override void DoSomething(IMyDto myInterface)
{
var concrete = myInterface as DtoOne;
// If concrete is not null..do stuff with DtoOne properties
}
}
public class ConcreteMakerTwo : AbstractMaker
{
public override void DoSomething(IMyDto myInterface)
{
var concrete = myInterface as DtoTwo;
// If concrete is not null..do stuff with DtoTwo properties
}
}
public class Customer
{
public void MakeSomething(IMyDto myDto)
{
var maker = GetMaker();
maker.DoSomething(myDto);
}
private AbstractMaker GetMaker()
{
//Stuff to determine if return ConcreteOne or ConcreteTwo
}
}
The code im not happy with is the:
var concrete = myInterface as DtoOne;
I would appreciate a lot if someone could give me some advide or tips about a pattern or good oop practice for this scenario.
It's not clear what all of your use cases are, but one option might be generics:
public abstract class AbstractMaker<T> where T:IMyDto
{
public abstract void DoSomething(T myInterface);
}
public class ConcreteMakerTwo : AbstractMaker<DtoTwo>
{
public override void DoSomething(DtoTwo myInterface)
{
// now you are certain that myInterface is a DtoTwo
}
}
I am not sure if I understand correctly what are you asking about, but why not just put method DoSomething in IMyDto and implement it differently in DtoOne, DtoTwo, etc.? There would be only one Maker and would always call the same method.
i need to do something like this in c#. But in the Exec(object) i got a compilation error.
public class ParentClass { }
public class class1 : ParentClass
{
}
public class class2 : ParentClass
{
}
public class class3 : ParentClass
{
}
public class MasterClass
{
public void ExecutionMethod(ParentClass myObject)
{
//some code
Exec(myObject);
//some code
}
public void Exec(class1 obj)
{
//some code
}
public void Exec(class2 obj)
{
//some code
}
public void Exec(class3 obj)
{
//some code
}
}
I solved using Reflection but i think must be a better approach, somebody could give me a nice idea
As #ScottChamberlain pointed out in the comments, you don't have any methods that take an argument of type ParentClass.
Take a look at the Liskov substitution principle - if you've done your implementation properly, you can substitute an instance of, for example, class1 for an instance of ParentClass, but the converse is not true at all.
Odds are, you don't need (or want) the overloads anyway. Just have ParentClass be an abstract class with an abstract Execute method that all child classes have to implement, then you can just call Execute on the class directly without bothering with the overloads. Even better, just make ParentClass an interface. (This is sometimes called the Strategy Pattern by the way).
public interface IParent {
void Execute();
}
public class class1 : ParentClass {
//Execute method implementation
}
public class class2 : ParentClass {
// ...
}
public class class3 : ParentClass {
// ....
}
public class MasterClass
{
public void ExecutionMethod(IParent myObject)
{
//some code
myObject.Execute();
//some code
}
}
I suggest you have a look at object-oriented design patterns. Specifically, the strategy pattern for this problem. Anyway, you can implement what you want like this:
public interface IParent
{
void Exec();
}
public class Child1 : IParent
{
void Exec() { /*code*/ }
}
public class Child2 : IParent
{
void Exec() { /*code*/ }
}
public class Child3 : IParent
{
void Exec() { /*code*/ }
}
public class MasterClass
{
public void ExecutionMethod(IParent myObject)
{
//some code
myObject.Exec();
//some code
}
}
You could also use an abstract class instead of an interface, if you wanted the parent class to have some functionality for the Exec method - then the child classes would have to override the method.
You can use command pattern, with dependency injection. I kind of give you an idea below. The concrete implementation will call execute on your receiver ( you logic goes there
public interface ICommand
{
void Execute();
}
public class Command1 : ICommand
{
public void Execute()
{
throw new NotImplementedException();
}
}
public class Command2 : ICommand
{
public void Execute()
{
throw new NotImplementedException();
}
}
public class Command3 : ICommand
{
public void Execute()
{
throw new NotImplementedException();
}
}
public class CommandManager
{
//you should use DI here to inject each concerete implementation of the command
private Dictionary<string, ICommand> _commands;
public CommandManager()
{
_commands = new Dictionary<string, ICommand>();
}
public void Execute(string key)
{
_commands[key].Execute();
}
}
The error your seeing is a result of your class1,2,3 objects being cast as their parent type because of the signature of the ExecutionMethod(xxx).
And not having an overridden method of Exec that takes a type of 'ParentClass' as the argument.
Probably the simplest method is to create an interface:
IDomainObject{}.
public class ParentClass : IDomainObject { }
public void ExecutionMethod(IDomainObject myObject)
{
Exec(myObject);
}
Using the interface in this way will prevent the downcast during the method call.
You need to use an interface here
Try changing ParentClass like this:
public interface IParentClass{}
Then make each of your classes implement it, like this:
public class class1 : IParentClass
{
}
public class class2 : IParentClass
{
}
Then in your MasterClass, try this:
public void ExecutionMethod(IParentClass myObject)
{
//some code
Exec(myObject);
//some code
}
public void Exec(IParentClass obj)
{
//some code
}
And then you can pass in any of your classes that implement the IParentClassinterface.
Now as an enhancement - if you want every implementation of IParentClass to have some methods and properties that you can invoke in your Exec method, do it like so:
public interface IParentClass
{
void DoTheThing();
}
This will force you to have this method in derived classes, so for example, class1 would look like this:
public class class1 : IParentClass
{
public void DoTheThing()
{
// things get done...
}
}
public class class2 : IParentClass
{
public void DoTheThing()
{
// things get done a different way...
}
}
And now in your Exec method, you can invoke like so:
public void Exec(IParentClass obj)
{
obj.DoTheThing();
}
Suppose you have the following class declarations:
public abstract class Foo
{
public class Bar
{
public virtual void DoSomething() { ... }
}
}
Is it possible to override Bar.DoSomething() in a child class of Foo, a la:
public class Quz : Foo
{
public override void Bar::DoSomething() { ... }
}
Obviously that syntax doesn't work, but is something like this possible?
No, but you can still inherit from the Foo.Bar class itself:
public class BarDerived : Foo.Bar
{
public override void DoSomething() { ... }
}
I feel I should explain that doing this will not mean that a class deriving from Foo will all of a sudden have an inner class of BarDerived instead, it just means that there is a class that can be derived from it. There are ways of replacing what type of class you want to use as the inner class, for example:
public class Foo<T>
where T : Foo.Bar
{
private T _bar = new T();
public class Bar
{
public virtual void DoSomething() { ... }
}
}
public class BarDerived : Foo.Bar
{
public override void DoSomething() { ... }
}
public class Quz : Foo<BarDerived> { ... }
No, only if you inherit from Bar
public class Quz : Foo.Bar
{
public override void DoSomething() { ... }
}
Well, if you are following good practices, then the Bar cannot be constructed by any other class then Foo, that said enables the following:
Create a derived class from Foo::Bar in Quz, and override it's DoSomething()
override each method in Foo where Bar is constructed and provide the derived class instead.
the user of Foo should not know the difference in API between Bar and your new derived inner class.
hope this makes sense.
Having these two methods declared in a non-generic class, which share the same signature:
private TypeResolverResult<T> TryRetrieveFromReusable<T>(TypeResolverConfiguration<T> typeResolverConfiguration) where T : class
{
return null;
}
private TypeResolverResult<T> BuildNew<T>(TypeResolverConfiguration<T> typeResolverConfiguration) where T : class
{
return null;
}
How can I create a delegate that represents these methods' signature?
I can't seem to get it, I tried:
private Func<TypeResolverConfiguration<T>, TypeResolverResult<T>> _typeResolveFunc;
But obvious this does not work because the class is non-generic and I can't change that.
Thanks
UPDATE
This is more or less what I need:
public class Manager : ATypeResolver, IManager
{
private neeedDelegate;
public Manager(RuntimeConfiguration runtimeConfiguration, IList<RepositoryContainer> repositories)
{
if (runtimeConfiguration.WhatEver)
{
neeedDelegate = TryRetrieveFromReusable;
}
else
{
neeedDelegate = BuildNew;
}
}
public override TypeResolverResult<T> Resolve<T>() where T : class
{
//Want to avoid doing this:
if (runtimeConfiguration.WhatEver)
{
TryRetrieveFromReusable(new TypeResolverConfiguration<T>());
}
else
{
BuildNew(new TypeResolverConfiguration<T>());
}
//and have just this
neeedDelegate<T>(new TypeResolverConfiguration<T>());
}
private TypeResolverResult<T> TryRetrieveFromReusable<T>(TypeResolverConfiguration<T> typeResolverConfiguration) where T : class
{
return null;
}
private TypeResolverResult<T> BuildNew<T>(TypeResolverConfiguration<T> typeResolverConfiguration) where T : class
{
return null;
}
}
Update From what I can see, an approach like this should work, as long as ATypeResolver has a where T : class on Resolve<T>:
public class Manager : ATypeResolver, IManager
{
private bool tryRetrieveFromReusable;
public Manager(RuntimeConfiguration runtimeConfiguration, IList<RepositoryContainer> repositories)
{
this.tryRetrieveFromReusable = runtimeConfiguration.WhatEver;
}
public override TypeResolverResult<T> Resolve<T>()
{
var typeResolver = tryRetrieveFromReusable ? (TypeResolver<T>)TryRetrieveFromReusable : BuildNew;
return typeResolver(new TypeResolverConfiguration<T>());
}
}
This uses a custom delegate type (a Func like you have should work too):
public delegate TypeResolverResult<T> TypeResolver<T>(
TypeResolverConfiguration<T> typeResolverConfiguration) where T : class;
If you like, you can move the var typeResolver = ... line to its own method, to separate the logic and allow you to use it from more than just Resolve. If you did that, Resolve might be as simple as: return GetTypeResolver<T>()(new TypeResolverConfiguration<T>());.
You seem to not understand exactly how generics work. I'll give a quick overview, but read the MSDN.
When you have a generic class
public class Foo<T>
{
public T Bar {get; set;}
}
And you use it something like this
Foo<int> intFoo = new Foo<int>();
Foo<string> stringFoo = new Foo<string();
At compile time, the compiler will detect the two usages of the generic type. It will create a type of each usage. So your assembly will have types that look something like this (no not exactly, but let's play pretend so that we humans can understand).
public class FooInt
{
public int Bar { get; set; }
}
public class FooString
{
public string Bar { get; set; }
}
And it will replace all uses of Foo<int> with FooInt and Foo<string> with FooString
Now if we have a non-generic class with a generic method
public class Foo
{
public T GetBar<T>() { ..... }
}
And you use it like this
Foo foo = new Foo();
int x = foo.GetBar<int>();
string s = foo.GetBar<string();
The compiler will generate
public class Foo
{
public int GetBarInt() { ..... }
public string GetBarString() { ..... }
}
And it will replace GetBar<T> with GetBarInt and GetBar<string> with GetBarString
But fields aren't like that. If you have a class that looks like so
public class Foo
{
public T Bar;
}
You cannot do this
Foo foo = new Foo();
foo.Bar<int> = 1;
foo.Bar<string> = "test";
The compiler just doesn't understand that. I'm not an expert on the internals, but my guess is that because this points to a place in memory, the compile cannot generate the generic usages at compile time.
But the point I am trying to make is this. Generics are not some magical "I don't need to specify the type" feature. They are hints to the compile that say "I am going to do this same thing multiple times, I want you to generate the code for me."
I know the title's a bit wordy, but I don't know how else to ask this question. This is basically the technique that I've been using to filter the types of objects you pass into an inherited class. Have a look at the code first and I'll explain more...
public interface IProjectile {}
public interface IPaintBall : IProjectile {}
public interface IPotato : IProjectile {}
public class Prop
{
public void Shoot(params IProjectile[] projectiles)
{
// logic goes here...
}
}
public class Car : Prop
{
public override void Shoot(params IPaintBalls[] paintBalls)
{
base.Shoot(paintBalls);
}
}
See? I don't want you to shoot my car with potatoes. You can only shoot it with paint-balls. So am I doing this the right way? Again, this gets way more complicated when the Prop class has like 100 functions that I also want to filter down to just paint-balls. I don't want to write-out those 100+ functions for the Car class, right? I especially don't want to write-out those 100+ functions for the 100+ Car classes that I'll be writing.
Am I being clear enough here?
This is just an example. I'm not doing game programming or anything like that. I'm just trying to give you guys a really simple example to convey what I want here. Basically, I don't want the code to compile if someone is trying to pass a potato to the Car's Shoot() function.
What I would probably do is to make Prop accept a Generic Type. I.e:
public class Prop<T> where T : IProjectile
{
public virtual void Shoot(params T[] projectiles)
{
// logic goes here...
}
}
public class Car : Prop<IPaintBall>
{
public override void Shoot(params IPaintBall[] projectiles)
{
base.Shoot(projectiles);
}
}
The methods are then exposed as PaintBalls for users of the Car class, i.e:
Car car = new Car();
car.Shoot(somePaintballs); // Shoot will only take IPaintBall.
You can then also have a non generic Prop class:
public class Prop : Prop<IProjectile>
{
}
Where you can still use:
public class Person : Prop
{
}
Person can be shot with any IProjectile, including IPotato.
If I understand correctly, I would go for generics:
public interface IProjectile { }
public interface IPaintBall : IProjectile { }
public interface IPotato : IProjectile { }
public abstract class Prop<TProjectile> where TProjectile : IProjectile
{
public void Shoot(params TProjectile[] projectiles)
{
}
}
public class Car : Prop<IPaintBall>
{
}
class Program
{
static void Main(string[] args)
{
Car myCar = new Car();
IPaintBall[] paintballs = PaintBallFactory.GetPaintBalls();
myCar.Shoot(paintballs);
}
}
Then you can't call Car.Shoot with nothing but paintballs.
It looks OK to me. Importantly you have used interfaces to abstract the implementation of a paint ball.
However your code is a little off:
public override void Shoot(params IPaintBall[] paintBalls)
{
base.Shoot(paintBalls);
}
Update: in this case, make the base class protected and expose a new method on the derived class, but use the base implementation.
public class Prop
{
protected void Shoot(params IProjectile[] projectiles)
{
// logic goes here...
}
}
public class Car : Prop
{
public void Shoot(params IPaintBall[] projectiles)
{
base.Shoot(projectiles);
}
}
Not tested in a compiler, but I believe basic arrays ([]) are co-variant.
Update 2: Alternatively, define an interface responsible for shooting and give it the Shoot method.
public interface IProjectile { }
public interface IPaintBall : IProjectile { }
public interface IPotato : IProjectile { }
public interface IShoot<T> where T : IProjectile
{
void Shoot(params T[] projectiles);
}
public interface IShootPaintBalls : IShoot<IPaintBall> { }
public class Prop : IShoot<IProjectile>
{
public void Shoot(params IProjectile[] projectiles)
{
// logic
}
}
public class Car : Prop, IShootPaintBalls
{
public void Shoot(params IPaintBall[] projectiles)
{
base.Shoot(projectiles);
}
}
Update 3: GenericTypeTea's response completes the generics circle :-), my current solution doesn't stop you shooting a car with a potato...
You cannot do this purely at compile time in .NET. To implement an interface you have to implement all its methods.
But explicit interface implementation will allow you to hide, to a degree, the inherited IProjectile method while providing a public IPaintBalls methods.
But there Prop doesn't make Shoot virtual, so you cannot override it anyway. And Prop is a class not an interface to explicit implementation doesn't apply.
It seems you will need to:
Make Prop.Shoot virtual, and
Accept the runtime check.
Something like this:
public class Prop {
public virtual void Shoot(params IProjectile[] projectiles) {
...
}
}
public class Car : Prop {
public override void Shoot(params IProjectile[] projectiles) {
foreach (var p in projectiles) {
if (!(p is IPaintBall)) {
throw new ArgumentException("Only shoot cars with paint balls");
}
}
Shoot(projectiles.Cast<IPaintBall>().ToArray());
}
public virtual void Shoot(params IPaintBall[] balls) {
// Allow callers that are calling with paint balls (know at compile time)
// to come in directly.
}
}
Create more interfaces, in this case a IShootableProjectile which inherits IProjectile. Same goes for Prop, it's a too general class.
Do not create interfaces or classes that can do a lot of different things. Break them down to small entites covering a specific responsibility. Read more about the following design principles:
http://blog.gauffin.org/2010/06/hello-world/