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();
}
}
Related
Please consider the attached figure.
What I want is that the (technical-) "User" can use methods from class A, B or C by an instantiate of "HeadClass". What I try to avoid is, that I have to add a separate function for each method defined in Class A, B and C to call them through the "HeadClass". I tried to describe this in an other stackoverflow-request yesterday but have deleted it because it seemed to be unclear what I wanted to achieve. So here is an other approach.
Usually this would be achieved by inheritance (if only one class would be inherited from). But, as they told me in that deleted post, I should use Interface instead. Now, so far I thought that I know how interface work (using almost for every class), but I can't figure how I achieve this describe problem.
How would I have to fill the "???" in "HeadClass"?
I am happy for any input. Thx in adavnce!
class User
{
public User(IHeadClass headObj)
{
_headObj = headObj
}
public DoStuff()
{
_headObj.Method_1
_headObj.Method_2
_headObj.HeadMethod
}
}
public class HeadClass : IHeadClass, ???
{
???
public HeadClass( ??? )
{
???
}
void HeadMethod()
{
... do head stuff
}
}
public class Class_A : IClass_A
{
public void Method_1 () { }
}
public class Class_B : IClass_B
{
public void Method_2 () { }
public void Method_3 () { }
}
public class Class_C : IClass_C
{
public void Method_4 () { }
}
I have check out this describing how to use interfaces instead. But this doesn't solve the above problem.
If I understand correctly you can use composition here. Something like this:
public interface IClass_A
{
void Method_1 ();
}
public interface IClass_B
{
void Method_2 ();
void Method_3 ();
}
public interface IClass_C
{
void Method_4 ();
}
public interface IHeadClass : IClass_A, IClass_B, IClass_C
{
void HeadMethod();
}
public class HeadClass : IHeadClass
{
private readonly IClass_A _a;
private readonly IClass_B _b;
private readonly IClass_C _c;
public HeadClass(IClass_A a, IClass_B b, IClass_C c)
{
_a = a;
_b = b;
_c = c;
}
void HeadMethod()
{
... do head stuff
}
public void Method_1() => _a.Method_1();
public void Method_2() => _b.Method_2();
public void Method_3() => _b.Method_3();
public void Method_4() => _c.Method_4();
}
C# (unlike for example C++ or PHP) does not support multiple inheritance. Interfaces allows multiple inheritance, but they don't provide definitions of methods, only declarations.
I think solution could be pattern called fasade: write methods in HeadClass that calls methods in other classes. In this case interfaces are not necessary.
public class HeadClass
{
private Class_A _a;
private Class_B _b;
private Class_C _c;
public HeadClass( Class_A a, Class_B b, Class_C c )
{
_a=a;
_b=b;
_c=c;
}
void HeadMethod()
{
... do head stuff
}
public void Method_1 () {
_a.Method_1();
}
public void Method_2 () {
_b.Method_2();
}
public void Method_3 () {
_b.Method_3();
}
public void Method_4 () {
_c.Method_4();
}
}
May I suggest instead that you have an interface passed instead of Class definition in your constructor?
public class HeadClass
{
private IMethod1 _method1;
private IMethod2 _method2;
private IMethod3 _method3;
private IMethod4 _method4;
public HeadClass( IMethod1 method1, IMethod2 method2, IMethod3 method3, IMethod4 method4)
{
_method1=method1;
_method2=method2;
_method3=method3;
_method4=method4;
}
void HeadMethod()
{
... do head stuff
}
public void Method_1 () {
_method1.Method_1();
}
public void Method_2 () {
IMethod2.Method_2();
}
public void Method_3 () {
IMethod3.Method_3();
}
public void Method_4 () {
IMethod4.Method_4();
}
}
Now you have removed any direct coupling to a class, you are no only linked by interface.
Say you want to split method 2 and 3 into it's own two classes? this code, never has to change.
You can now reuse any class that has a definition of the interface, as a paramater. No code is defined twice, that does the same thing, in each input.
Because:
public class Method1 : IMethod1
{
}
public class Method2 : IMethod2
{
}
public class Method3 : IMethod3
{
}
public class Method4 : IMethod4
{
}
can now be parsed as parameters to HeadClass.
or, if you insist method 2 & 3 belong on the same class.
public class ClassA: IMethod1
{
}
public class ClassB: IMethod2, IMethod3
{
}
public class ClassC: IMethod4
{
}
Should be obvious from this example that the benefits lie in the fact that you can now do whatever you want in Headclass, and if you need behaviour to change, you can inject code via constructor, without having to retry the behaviour of headclass.
And headclass, doesn't know ClassA, B or C exist directly, only the interface.
I Believe this is called the Strategy pattern?
Suppose I have a Customer class. A customer can have multiple kinds of loyalty points. For one promotion, the customer may be collecting Rewards. In another, the customer may be collecting Miles. And there is no fixed number of kinds of loyalty points that the Customer is built for. I am sure this is a common use case. Is the decorator pattern a good fit given below sample code?
public interface ICustomer
{
void Display();
}
public class SimpleCustomer : ICustomer
{
public void Display()
{
Console.WriteLine("I am simple customer");
}
}
public abstract class CustomerDecorator : ICustomer
{
protected ICustomer customer;
public CustomerDecorator(ICustomer customer)
{
this.customer = customer ?? throw new ArgumentNullException("customer");
}
public abstract void Display();
}
public class RewardsDecorator : CustomerDecorator
{
private int rewards;
public RewardsDecorator(ICustomer customer, int rewards) : base(customer)
{
this.rewards = rewards;
}
public override void Display()
{
Console.WriteLine("Now I have " + rewards.ToString() + " rewards");
}
}
public class MilesDecorator : CustomerDecorator
{
private int miles;
public MilesDecorator(ICustomer customer, int miles) : base(customer)
{
this.miles = miles;
}
public override void Display()
{
Console.WriteLine("Now I have " + miles.ToString() + " miles");
}
}
Don't think Decorator pattern does what you want it to do. Decorator adds new functionalities on top of the original class. A typical wiki example would say, we can add scroll bar, menu bar, overlays and other UI components on top of canvas. So to make a proper browser window, so you will have:
public class Canvas
public class ScrollableCanvas
public class OverlayedCanvas
etc.
So that we add more functionalities to the original Canvas.
To solve your problem, you should have something like:
public abstract class LoyaltyProgramAccount {...}
public class RewardAccount extends LoyaltyProgramAccount {...}
public class MilesAccount extends LoyaltyProgramAccount {...}
And then add a registery-ish enum:
public enum LoyaltyProgramTypes {
miles,
reward,
}
and then let user be:
public class Customer {
private List<LoyaltyProgramTypes, LoyaltyProgramAccount> accounts;
public void openAccount(LoyaltyProgramTypes type, LoyaltyProgramAccount account) {
accounts.put(type, account);
}
...
}
I do not think that Decorator is the pattern you are looking for.
Besides, your code does not seem to be an implementation of the Decorator pattern. You do not add any functionality to the only function. You just override it. But adding to the existing function is what the Decorator pattern is all about.
My approach would be state / strategy pattern. There are different kinds of rewards. And a customer has one or more of them. These rewards may share a common interface and provide different implementations. The customer (or a subclass or compound object RewardedCustomer) should hold a list or map of these rewards.
I would use the visitor pattern, this is pretty ideal for your situation. This will allow you nicely separate the rewards calculations for you different customer types and run operations against all supported rewards types.
class Program
{
static void Main(string[] args)
{
MilesCustomer customer = new MilesCustomer();
ICustomerVisitor<int> visitor = new MilesCalculation(10);
var miles = customer.Visit(visitor);
visitor = new RewardsCalucation(100);
var rewards = customer.Visit(visitor);
}
}
public interface ICustomerVisitor<T>
{
T Visit(SimpleCustomer cusomter);
T Visit(RewardsCustomer cusomter);
T Visit(MilesCustomer cusomter);
}
public abstract class Customer
{
public Customer()
{
TotalMoneySpent = 10;
}
public int TotalMoneySpent { get; private set; }
public abstract T Visit<T>(ICustomerVisitor<T> visitor);
public virtual void Display()
{
Console.WriteLine("I am simple customer");
}
}
public class RewardsCalucation : ICustomerVisitor<int>
{
private int _rewardsPerDollar;
public RewardsCalucation(int rewardsPerDollar) => _rewardsPerDollar = rewardsPerDollar;
public int Visit(SimpleCustomer cusomter)
{
return 0;
}
public int Visit(RewardsCustomer cusomter)
{
return cusomter.TotalMoneySpent * _rewardsPerDollar;
}
public int Visit(MilesCustomer cusomter)
{
return 0;
}
}
public class MilesCalculation : ICustomerVisitor<int>
{
private int _milesPerDollar;
public MilesCalculation(int milesPerDollar) => _milesPerDollar = milesPerDollar;
public int Visit(SimpleCustomer cusomter)
{
return 0;
}
public int Visit(RewardsCustomer cusomter)
{
return 0;
}
public int Visit(MilesCustomer cusomter)
{
return cusomter.TotalMoneySpent * _milesPerDollar;
}
}
public class SimpleCustomer : Customer
{
public override T Visit<T>(ICustomerVisitor<T> visitor)
{
return visitor.Visit(this);
}
}
public class RewardsCustomer : Customer
{
public override T Visit<T>(ICustomerVisitor<T> visitor)
{
return visitor.Visit(this);
}
}
public class MilesCustomer : Customer
{
public override T Visit<T>(ICustomerVisitor<T> visitor)
{
return visitor.Visit(this);
}
}
I want to reuse Cook method functionality, but still pass different parameters to execute:
public void Cook(BasicRequest request,IBaseInterface base)
{
// Some code
// More code
request.Execute(base);
}
public class BasicRequest
{
public abstract void Execute(IBaseInterface baseInterface)
}
public class RequestA : BasicRequest
{
public void Execute(IBaseInterface base)
{
var derived = (DerivedClassA)base;
// Do stuff with derived
}
}
public class RequestB : BasicRequest
{
public void Execute(IBaseInterface base)
{
var derived = (DerivedClassB)base;
// Do stuff with derived
}
}
public interface IDerivedClassA : IBaseInterface {}
public interface IDerivedClassB : IBaseInterface {}
I have a design issue here that casting is needed on each of requests execute methods.
How can I make this code cleaner ?
You should be using generics.
Update the BaseRequest to a generic class:
public abstract class BasicRequest<T> where T:IBaseInterface
{
public abstract void Execute(T baseInterface);
}
Change your class Cook method as follows:
public void Cook<T>(BasicRequest<T> request, T ibase) where T:IBaseInterface
{
// Some code
// More code
request.Execute(ibase);
}
Change your classes,
public class RequestA : BasicRequest<DerivedClassA>
{
public override void Execute(DerivedClassA ibase)
{
// Do stuff with derived
}
}
public class RequestB : BasicRequest<DerivedClassB>
{
public override void Execute(DerivedClassB ibase)
{
// Do stuff with derived
}
}
Hi everyone I am programming in Unity3d with C# and while I was writing my code I stumbled with a little issue, I write to you an example because I dont know explain me.
class Base
{
public string name;
}
class Derived : Base
{
public void Gun();
}
class BasePlayer
{
public Base x;
}
class SoldierPlayer : BasePlayer
{
}
The situation is this, I want to do something like that
SoldierPlayer.x.Gun();
But I don't know how do it
The real case is this
public class BasePlayerController : MonoBehaviour
{
public BasePlayerManager playerManager;
...
public class RobotPlayerController : BasePlayerController {
...
playerManager = gameObject.AddComponent<RobotPlayerManager>();
And I will use new methods
UPDATE 1
I did a example better, I want to do in Base Controller manager.user.energy and be treated as the next type RobotManager.RobotUser.energy
BaseController
BaseManager
BaseUser
class BaseController
{
BaseManager manager;
public virtual void Move(int x,int y)...
}
class BaseManager {
BaseUser user;
public virtual Pause(bool state);
}
class BaseUser {
int life
}
RobotController
RobotManager
RobotUser
class RobotController : BaseController
{
// manager as RobotManager?
public void Ray(int x,int y);
}
class RobotManager : BaseManager
{
// user as RobotUser?
}
class RobotUser : BaseUser
{
int energy;
}
UPDATE 2
I seek to do this
public Run()
{
RobotController rc = new RobotController();
rc.manager.energy;
}
You can't call SoldierPlayer.x.Gun(); because SoldierPlayer.x has type Base which has not method Gun(). OOP world and C# can provide you many solutions, your choose depends on your goals.
some of them (order by best practise):
1) Overriding Polymorphism. Add .Gun() method to Base class and implemend it in derived classes. For example
class Base
{
public string name;
public void virtual Gun()
{
Trace.Log("I'm base class, i can't do anything");
}
}
class Derived : Base
{
public override void Gun()
{
Consule.WriteLine("Hello i have gun");
}
}
class Derived2 : Base
{
public override void Gun()
{
Consule.WriteLine("Hello i have 2 guns");
}
}
2) Overloading Polymorphism In many source this method is mentioned like some kind of polymorphism AD-HOC
public void GunAction(Derived2 o)
{
o.Gun();
}
public void GunAction(Derived1 o)
{
o.Gun();
}
public void GunAction(Base o)
{
Trace.Log("I'm base class, i can't do anything");
}
3) is-cast
public void GunAction(Base o)
{
if(o is Derived1 )
o.Gun();
if(o is Derived2 )
o.Gun();
}
UPDATE 1 answering to your new requirements
class BaseController
{
public BaseManager manager;
...
class RobotController1 : BaseController
{
// manager as RobotManager? - no it is stil BaseManager
public void Ray(int x,int y);
}
class RobotController2 : BaseController
{
// manager as RobotManager? - yes. now it is RobotManager
public void Ray(int x,int y);
public RobotController2()
{
manager = new RobotManager();
}
}
public void Run()
{
var controller = new RobotController2();// you have RobotManager
controller.manager = new BaseManager();// it is again BaseManager
}
I have used delegates to represent methods - but I now have many classes that have same methods (but different code in those methods).
Is there a way to delegate the entire class?
Pseudo code:
class myModelA
{
void update()
{
}
}
class myModelB
{
void update()
{
}
}
delegate class myModel;
if (x==1)
myModel = myModelA;
else
myModel = myModelB;
myModel.update();
I know I can delegate the "üpdate" method BUT in real world I have lots of methods and I would rather just simply delegate the class.
EDIT1 based on Jon Skeet's answer
BUT how do I declare a public variable? (non public variables compile OK)
public interface IModel
{
double myDouble; <<<< this gives an error
void Update();
}
public class MyModelA : IModel
{
public double myDouble;
public void Update() { ... }
}
public class MyModelB : IModel
{
public double myDouble;
public void Update() { ... }
}
No, in this case you don't want a delegate - you want an interface.
You create an interface which all of your classes implement:
public interface IModel
{
void Update();
}
public class MyModelA : IModel
{
public void Update() { ... }
}
public class MyModelB : IModel
{
public void Update() { ... }
}
Then:
IModel model;
if (x == 1)
{
model = new MyModelA();
}
else
{
model = new MyModelB();
}
model.Update();
As Jon Skeet, I think you need to use interfaces.
A little changed code from
http://www.dotnetperls.com/interface
using System;
interface IPerl
{
void Read();
}
class TestA : IPerl
{
public void Read()
{
Console.WriteLine("Read TestA");
}
}
class TestB : IPerl
{
public void Read()
{
Console.WriteLine("Read TestB");
}
}
class Program
{
static void Main()
{
IPerl perl = new TestA(); // Create instance.
perl.Read(); // Call method on interface.
}
}