The naive solution, to move the lock to the Parent class, has a different behaviour: I will not be able to call new Child1().Method1() and new Child2().Method1() simultaneously.
Is there any way to refactor the code below?
abstract class Parent
{
protected abstract Method1();
}
class Child1 : Parent
{
static object staticLock = new object();
public void Method1()
{
lock(staticLock)
{
// Do something ...
}
}
}
class Child2 : Parent
{
static object staticLock = new object();
public void Method1()
{
lock(staticLock)
{
// Do something else ...
}
}
}
I'm asking this because it's not only 2 child classes, so the real problem is bigger.
Have a method implemented by each child class that provides lock policy and move Method1 to base class as in your other question.
class Parent
{
public void Method1()
{
using(acquireLock())
{
Method1Impl();
}
}
protected abstract IDisposable acquireLock();
protected abstract void Method1Impl();
}
class Child : Parent
{
protected override IDisposable acquireLock()
{
// return some class that does appropriate locking
// and in Dispose releases the lock.
// may even be no-op locking.
}
}
Maybe this works
abstract class Parent
{
protected abstract object StaticLock { get; }
public void Method()
{
lock(staticLock)
{
MethodImpl();
}
}
protected abstract MethodImpl();
}
class Child1 : Parent
{
private static object staticLock = new object();
protected override object StaticLock { get { return staticLock; } }
protected override MethodImpl()
{
// Do something ...
}
}
class Child2 : Parent
{
private static object staticLock = new object();
protected override object StaticLock { get { return staticLock; } }
protected override MethodImpl()
{
// Do something else ...
}
}
Related
When this code runs the output is "Child running" even though I am casting it to the Parent class? Im probably doing it wrong, if so, how can i achieve the desired result of having an output of "Parent running"? The Parent instance = new Child(); has to remain like that.
class Program
{
class Parent
{
public virtual void Run()
{
Console.WriteLine("Parent running.");
}
}
class Child : Parent
{
public override void Run()
{
Console.WriteLine("Child running.");
}
}
static void Main(string[] args)
{
Parent instance = new Child();
(instance as Parent).Run();
Console.ReadLine();
}
}
EDIT:
Noticed if I remove the virtual keyword from the Parent class and mark the Child's version of this method as new it "solves" the issue.
class Program
{
class Parent
{
public void Run()
{
Console.WriteLine("Parent running.");
}
}
class Child : Parent
{
public new void Run()
{
Console.WriteLine("Child running.");
}
}
static void Main(string[] args)
{
Parent instance = new Child();
(instance as Parent).Run();
Console.ReadLine();
}
}
You basically can't (short of using tricks with reflection). That's how inheritance in C# works.
What you could do instead of overriding Run is to shadow it:
public class Parent
{
public void Run() => Console.WriteLine("Parent");
}
public class Child : Parent
{
public new void Run() => Console.WriteLine("Child");
}
var child = new Child();
child.Run(); // prints "Child"
((Parent)child).Run(); // prints "Parent"
Shadowing is rarely a good idea as it can be confusing when an object changes its behaviour depending on the type of its variable. For more on shadowing, have a look at e. g. this question.
virtual method should not do anything,it's just a contract,what your goal is a bad ideal.
you should do it like this:
public class animal
{
public virtual void eat()
{
//don't do anything
}
}
public class dog:animal
{
public override void eat()
{
//eat Meat
}
}
public class sheep:animal
{
public override void eat()
{
//eat grass
}
}
My goal is to have the Abstract class update on its own once Consume is called on one of the derived classes.
Imagine this:
public interface IConsumable
{
void Consume();
}
public abstract class AbstractConsumable : IConsumable
{
private bool _consumed = false;
public virtual void Consume()
{
_consumed = true;
}
}
public class HealthyConsumable: AbstractConsumable
{
public override void Consume()
{
// Do something healthy and ...
base.Consume(); // Would like to avoid this...
}
}
public class PoisonousConsumable: AbstractConsumable
{
public override void Consume()
{
// Do something poisonous and ...
base.Consume(); // Would like to avoid this...
}
}
What I would like to achieve here is not having to call base.Consume() on the override methods, but still have the abstract class set _consumed once the derived classes call their Consume() methods.
You could make Consume none virtual and within it you called another protected virtual (or abstract method) that can contain code that be change by sub classes. Consumers of your class can only call the public Consume method but this will intern call the sub class implementation specific code
public interface IConsumable
{
void Consume();
}
public abstract class AbstractConsumable : IConsumable
{
private bool _consumed = false;
public void Consume()
{
_consumed = true;
InternalConsumerBehaviour();
}
protected virtual void InternalConsumeBehaviour()
{
//default do nothing could potentially mark this method abstract rather than virtual its up to you
}
}
public class HealthyConsumable: AbstractConsumable
{
protected override void InternalConsumeBehaviour()
{
// Do something healthy and ...
}
}
public class PoisonousConsumable: AbstractConsumable
{
protected override void InternalConsumeBehaviour()
{
// Do something poisonous and ...
}
}
If I get what you're asking right you could do something like this:
public interface IConsumable
{
void Consume();
}
public abstract class AbstractConsumable : IConsumable
{
private bool _consumed = false;
public abstract void ConsumeEffects();
public void Consume()
{
this.ConsumeEffects();
_consumed = true;
}
}
public class HealthyConsumable: AbstractConsumable
{
public override void ConsumeEffects()
{
// Do something healthy and ...
// Consume will get called in the base
}
}
public class PoisonousConsumable: AbstractConsumable
{
public override void ConsumeEffects()
{
// Do something poisonous and ...
// Consume will get called in the base
}
}
I've found some code that is a bit long in a method:
class Parent { }
class Son : Parent { }
class Daughter : Parent { }
class MainClass
{
private void Iterate(IEnumerable<Parent> list)
{
foreach (Parent item in list) {
if (item is Son) {
...SOME CODE...
}
else if (item is Daughter) {
...MORE CODE...
}
}
}
}
Because of this big if-else block, the method is quite large, and smells as bad design (OOP-wise).
I've tried to come up with something a bit more polymorphic, taking advantage of method-overloading via different type-paramaters, such as:
class MainClass
{
private static void DoSomething (Son son)
{
Console.WriteLine ("Son");
}
private static void DoSomething (Daughter daughter)
{
Console.WriteLine ("Daughter");
}
private static void DoSomething (Parent parent)
{
Console.WriteLine ("Parent");
}
private void Iterate(IEnumerable<Parent> list)
{
foreach (var item in list) {
DoSomething (item);
}
}
}
But this doesn't work because it always prints "Parent", so I guess I would need to downcast manually, which defeats the point a bit, and would not look elegant.
One last point: if you are tempted to recommend me to put the implementation of DoSomething in the derived classes of Parent, that is not possible, because of dependency problems (the assembly where these 3 classes live cannot have dependencies on some things that the SOME CODE and MORE CODE is calling).
So what would be the best approach to refactor this? Thanks!
There are several ways to do this asides from the switch statement you've already identified (which definitely gets clunky with more than a couple of types involved).
First of all, if you aren't likely to add subtypes, but you are likely to add other things to do with the subtypes, you can use the Visitor Pattern to mimic double dispatch.
class Parent
{
public abstract void Accept(IChildVisitor visitor);
}
class Son : Parent
{
public override void Accept(IChildVisitor visitor)
{
visitor.Visit(this);
}
}
class Daughter : Parent
{
public override void Accept(IChildVisitor visitor)
{
visitor.Visit(this);
}
}
interface IChildVisitor
{
Visit(Son son);
Visit(Daughter daughter);
}
class SomeCodeChildVisitor : IChildVisitor
{
public Visit(Son son)
{
...SOME CODE...
}
public Visit(Daughter daughter)
{
...SOME CODE...
}
}
class MainClass
{
private void Iterate(IEnumerable<Parent> list)
{
foreach (Parent item in list) {
item.Accept(new SomeCodeChildVisitor());
}
}
}
You can also use a Dictionary<Type,Action>
class Parent { }
class Son : Parent { }
class Daughter : Parent { }
class MainClass
{
// If you don't actually need a reference to the child
private void IDictionary<Type, Action> map =
new Dictionary<Type, Action>()
{
{ typeof(Son), () => ...SOME CODE... }
{ typeof(Daughter), () => ...SOME CODE... }
};
// If you do need a reference to the child
private void IDictionary<Type, Action<Parent>> otherMap =
new Dictionary<Type, Action<Parent>>()
{
{ typeof(Son), x => (Son)x. ...SOME CODE... }
{ typeof(Daughter), y => (Daughter)x. ...SOME CODE... }
};
private void Iterate(IEnumerable<Parent> list)
{
foreach (Parent item in list) {
// either
map[item.GetType()]();
// or
otherMap[item.GetType()](item);
}
}
}
You can also use the dynamic keyword
class Parent { }
class Son : Parent { }
class Daughter : Parent { }
class MainClass
{
private void Iterate(IEnumerable<Parent> list)
{
foreach (Parent item in list) {
Visit((dynamic)item);
}
}
private void Visit(Son son)
{
...SOME CODE...
}
private void Visit(Daughter daughter)
{
...SOME CODE...
}
}
You can also just filter the types straight out of your collection with Linq (especially if you only care about some subtypes and not others, e.g. if you're iterating through a Controls collection and you only care about Buttons)
class Parent { }
class Son : Parent { }
class Daughter : Parent { }
class MainClass
{
private void Iterate(IEnumerable<Parent> list)
{
foreach (Daughter daughter in list.OfType<Daughter>()) {
...SOME CODE...
}
}
}
In C# I generally recommend the dictionary approach, but any will do in a pinch.
The best situation is to move DoSomething() method to the classes. If not possible, maybe you still can use conditionals to polymorphism, but with the decorator pattern. In this case you can
Define an abstract class with an abstract method DoSomething(). Let's call it FamilyDecorator. It's a good idea to create a constructor which receives a Parent in his parameter, so you can save it as a protected variable (that means: visible to all of the derived classes).
Declare one decorator for each class on your assembly: ParentDecorator, SonDecorator, DaughterDecorator. These three classes inherit from FamilyDecorator and must override the DoSomething() method.
The trick is to create a method in the abstract class that returns one or another Decorator, based on type. That's the way you can separate which logic use on each case:
abstract class FamilyDecorator
{
protected Domain.Parent _member;
public abstract void DoSomething();
internal FamilyDecorator(Domain.Parent member)
{
_member = member;
}
public static FamilyDecorator GetDecorator(Domain.Parent item)
{
if(item.GetType() == typeof(Domain.Parent))
{
return new ParentDecorator(item);
}
else if (item.GetType() == typeof(Domain.Son))
{
return new SonDecorator(item);
}
else if (item.GetType() == typeof(Domain.Daughter))
{
return new DaughterDecorator(item);
}
return null;
}
}
class ParentDecorator : FamilyDecorator
{
internal ParentDecorator(Domain.Parent parent)
: base(parent)
{
}
public override void DoSomething()
{
Console.WriteLine("A parent");
}
}
class SonDecorator : FamilyDecorator
{
internal SonDecorator(Domain.Parent son)
: base(son)
{
this._member = son;
}
public override void DoSomething()
{
Console.WriteLine("A son");
}
}
class DaughterDecorator : FamilyDecorator
{
internal DaughterDecorator(Domain.Parent daughter)
: base(daughter)
{
}
public override void DoSomething()
{
Console.WriteLine("A daughter");
}
}
Then, in your Main class:
foreach (Parent item in list)
{
var decorator = FamilyDecorator.GetDecorator(item);
decorator.DoSomething();
}
This solution keeps the code very clean and takes advantage of polymorphism.
Edit
I don't think I like this solution because you're basically moving the
type checking from the foreach loop to the GetDecorator() method.
Polymorphism should allow you to do this without type checking
manually.
There is another solution, based on the same idea: to use reflection for the object construction.
In this case:
Instead of an abstract class you define an Interface that declares the DoSomething() method.
Now each decorator inherits from their corresponding class (Parent - ParentDecorator, Son - SonDecorator, etc.)
You need to change the constructors in the Decorator classes. They need to be public if you want to use reflection.
Finally, the GetDecorator() method just search for the derived class in the assembly. If found, it returns the decorator.
namespace FamilyNamespace
{
interface IFamily
{
void DoSomething();
}
class ParentDecorator : Domain.Parent, IFamily
{
private Domain.Parent _member;
public ParentDecorator(Domain.Parent parent)
{
this._member = parent;
}
public void DoSomething()
{
Console.WriteLine("A parent");
}
}
class SonDecorator : Domain.Son, IFamily
{
private Domain.Parent _member;
public SonDecorator(Domain.Parent son)
{
this._member = son;
}
public void DoSomething()
{
Console.WriteLine("A son");
}
}
class DaughterDecorator : Domain.Daughter, IFamily
{
private Domain.Parent _member;
public DaughterDecorator(Domain.Parent daughter)
{
this._member = daughter;
}
public void DoSomething()
{
Console.WriteLine("A daughter");
}
}
}
Then in your Main class:
static FamilyNamespace.IFamily GetDecorator(Domain.Parent item)
{
var baseType = item.GetType();
var derivedType = Assembly.GetExecutingAssembly().GetTypes().Where(m => m != baseType && baseType.IsAssignableFrom(m));
if (derivedType.Any())
{
return (FamilyNamespace.IFamily)Activator.CreateInstance(derivedType.First(), new object[] { item });
}
return null;
}
... and the Main method:
foreach (Domain.Parent item in list)
{
var decorator = (FamilyNamespace.IFamily)GetDecorator(item);
decorator.DoSomething();
}
Greetings
is this possible to somehow, have this scenario, where A.N inherits code from A with this code example?
The reason for setting it up like this, is that I need multiple classes that inherit from Base<TType> and the Nested : Base<TType> where the server has the base only, and the client has the extended Nested. This way, it would be easy to use the code, where they would have some shared code between themselves & each other.
The problem is that I would have to write identical code inside the
A and A.N
B and B.N
C and C.N
etc.
I have solved this temporarily, by replacing the Nested abstract class, with an Interface and doing
A.N : A, INested, but now I have to rewrite the Base<TType>.Nested code again inside all the Nested classes. For now, the nested class is small & managable.
hope this isn't a confusing question...
public abstract class Base<TType> where TType : class
{
public TType data;
internal void CommonCodeForAll() { }
public abstract void Update();
public abstract class Nested : Base<TType>
{
public abstract void Input();
}
}
public class A : Base<someClass>
{
public float Somevariable;
public void SpecificFunctionToA() { }
public override void Update()
{
// code that gets executed on server & client side that is unique to A
}
public class N : A.Nested
{
public override void Input()
{
if (data.IsReady()) { Somevariable *= 2; }
SpecificFunctionToA();
}
}
}
public class B : Base<anotherClass>
{
public float Somevariable;
public int index;
public int[] Grid;
public void SomethingElse() { }
public override void Update()
{
// code that gets executed on server & client side that is unique to B
}
public class N : B.Nested
{
public override void Input()
{
if (Grid[index] == -1) { SomethingElse(); }
data.Somevariable = Grid[index];
}
}
}
Edit:
I updated the code example to show what I'm trying to achieve.
Why I am trying to do this, is to keep the physics, networking & User input seperate.
There are multiple different controllers where each one has their own pack & unpacking functions, controller identity & access to the physics engine.
I have a solution using ecapsulation of classes instead of inheritance.
public abstract class BaseGeneric<T>
{
T data;
// ctor
protected BaseGeneric(T data)
{
this.data=data;
}
// methods
public abstract void Update();
// properties
public T Data
{
get { return data; }
set { data=value; }
}
// base nested class
public abstract class BaseNested<B> where B : BaseGeneric<T>
{
protected B #base;
// ctor
protected BaseNested(B #base)
{
this.#base=#base;
}
// methods
public abstract void Input(T data);
public void Update() { #base.Update(); }
// properties
public T Data
{
get { return #base.data; }
set { #base.data=value; }
}
}
}
// implementation base
public class Base : BaseGeneric<int>
{
// ctor
protected Base(int data) : base(data) { }
//methods
public override void Update()
{
this.Data+=1;
}
// implemented nested class
public class Nested : Base.BaseNested<Base>
{
// ctor
public Nested(int data) : base(new Base(data)) { }
public Nested(Base #base) : base(#base) { }
// methods
public override void Input(int data)
{
this.Data=data;
}
}
}
class Program
{
static void Main(string[] args)
{
// new implemented class with value 0
var nested=new Base.Nested(0);
// set value to 100
nested.Input(100);
// call update as implemented by `Base`.
nested.Update();
}
}
Here's some pseudo code to illustrate what I'm looking at.
public class Loader
{
public Execute()
{
var currentPage = new ItemPageDocumentBuilder();
while(reader.Read())
{
currentPage.Add(reader.XmlDoc);
}
}
private class ItemsToLoad
{
private XmlDocument _page
public void Add(XmlElement itemelement)
{
_page.DocumentElement.AppendChild(itemElement);
}
}
}
I need to derive a class from Loader, and then override the Add method of the ItemsToLoad class inside it, and then call base.Execute(). In other words I want the Execute() method of my derived class to be exactly the same as that of Loader, but to use the overridden Add method of ItemsToLoad to to its work.
I suspect the neatest way to do this would be to remove ItemsToLoad from inside Loader, and make it abstract, correct?
If I couldn't do that, out of interest, what's the best solution?
If I understand your requirement, you have two responsabilities: executing something (which is always the same), and adding something (which differs).
I would do it much simpler, without inheritance and inner classes.
For the adding task, you define an interface:
public interface IItemAdder
{
void Add();
}
And one ore more implementations:
public class ItemAdder1 : IItemAdder
{
public void Add()
{
// specific implementation here
}
}
Then, you have a Loader, in which you inject a specific instance of item adder:
public class Loader : ILoader
{
private IItemAdder _itemAdder;
public Loader(IItemAdder itemAdder)
{
_itemAdder = itemAdder;
}
public void Execute()
{
// use injected item adder to do work
_itemAdder.Add();
}
}
public interface ILoader
{
void Execute();
}
And so usage is:
var loader = new Loader(new ItemAdder1());
loader.Execute();
This way everything is injected, can be replaced and mocked easily; and you clearly separate concerns.
Here is a suggestion (Syntax might not be correct though):
public class Loader
{
ItemsToLoad item;
public Loader(ItemsToLoad item) {
this.item = item;
}
public Execute()
{
// do things using item like item.add();
}
}
interface ItemsToLoad
{
void add();
}
class ItemsToLoad1: ItemsToLoad
{
void add(){
// implementation
}
}
class ItemsToLoad2: ItemsToLoad
{
void add(){
// implementation
}
}
And here is how to use them;
ItemsToLoad item;
if (some condition) {
item = new ItemsToLoad1()
} else {
item = new ItemsToLoad2()
}
Loader loader = new Loader(item);
loader.execute();
You can inherit both classes and inject child sub-class object to its parent.
class Loader
{
public void Execute(ItemsToLoad argObj)
{
if(argObj == null)
argObj = new ItemsToLoad();
argObj.Add(19);
}
public class ItemsToLoad
{
public virtual void Add(int a)
{
Console.WriteLine("Reached ItemsToLoad.");
}
}
}
class ChildLoader:Loader
{
public void Execute(ItemsToLoad argObjLoader)
{
if (argObjLoader == null)
argObjLoader = new ChildItemsToLoad();
base.Execute(argObjLoader);
}
class ChildItemsToLoad : Loader.ItemsToLoad
{
public override void Add(int b)
{
Console.WriteLine("Reached ChildItemsToLoad.");
}
}
}
And can start with
ChildLoader obj999 = new ChildLoader();
obj999.Execute(null);
I need to derive a class from Loader, and then override the Add method of the ItemsToLoad class inside it, and then call base.Execute(). In other words I want the Execute() method of my derived class to be exactly the same as that of Loader, but to use the overridden Add method of ItemsToLoad to to its work.
You need to override Loader, not ItemsToLoad. You haven't shown the code that uses ItemsToLoad, so it's difficult to be specific - but at the very least, you would need to override the new ItemsToLoad to point to your subclass. Also, ItemsToLoad is private - meaning you can't use it except from within Loader. As it is now, you'd need a completely rewritten ItemsToLoad and to override every method in Loader that uses ItemsToLoad.
If you control the Loader class, the easiest changes would probably be to abstract out the creating of ItemsToLoad and open up ItemsToLoad so it can be subclassed. Something like:
public class Loader {
private ItemsToLoad Items { get; set; }
protected virtual ItemsToLoad CreateItemsToLoad() {
return new ItemsToLoad();
}
protected class ItemsToLoad {
public virtual void Add() {
}
}
}
public class MyOtherLoader : Loader {
protected override ItemsToLoad CreateItemsToLoad() {
return new MyOtherItemsToLoad();
}
private class MyOtherItemsToLoad : ItemsToLoad {
public override void Add() {
}
}
}