I have an abstract class A, where I have derived the classes B and C.
Class A provides an abstract method DoJOB(), which is implemented by both derived classes.
There is a class X which has methods inside, which need to call DoJOB().
The class X may not contain any code like B.DoJOB() or C.DoJOB().
Example:
public class X
{
private A foo;
public X(A concrete)
{
foo = concrete;
}
public FunnyMethod()
{
foo.DoJOB();
}
}
While instantiating class X I want to decide which derived class (B or C) must be used.
I thought about passing an instance of B or C using the constructor of X.
X kewl = new X(new C());
kewl.FunnyMethod(); //calls C.DoJOB()
kewl = new X(new B());
kewl.FunnyMethod(); // calls B.DoJOB()
My test showed that declaring a method with a parameter A is not working. Am I missing something?
How can I implement this correctly?
(A is abstract, it cannot be instantiated)
EDIT:
Sorry, I forgot sth.
class A is a generic abstract singleton:
abstract public class A<T> where T : A<T>
{
....
}
public sealed class B : A<B>
{
.....
}
public sealed class C : A<C>
{
.....
}
See the example:
http://www.c-sharpcorner.com/UploadFile/snorrebaard/GenericSingleton11172008110419AM/GenericSingleton.aspx
Under the head line "The solution with the Generic Singleton as an abstract class"
You must have made a mistake in the test, the code works fine:
void Main()
{
X kewl = new X(new C());
kewl.FunnyMethod(); //calls C.DoJOB()
kewl = new X(new B());
kewl.FunnyMethod(); // calls B.DoJOB()
}
public class X
{
private A foo;
public X(A concrete)
{
foo = concrete;
}
public void FunnyMethod()
{
foo.DoJOB();
}
}
public abstract class A
{
public abstract void DoJOB();
}
public class B : A
{
public override void DoJOB()
{
Console.WriteLine("B");
}
}
public class C : A
{
public override void DoJOB()
{
Console.WriteLine("C");
}
}
Outputs :
C
B
For your edit:
void Main()
{
var kewl = new X<C>(new C());
kewl.FunnyMethod(); //calls C.DoJOB()
var kewl2 = new X<B>(new B());
kewl2.FunnyMethod(); // calls B.DoJOB()
}
public class X <T> where T : A<T>
{
private A<T> foo;
public X(A<T> concrete)
{
foo = concrete;
}
public void FunnyMethod()
{
foo.DoJOB();
}
}
public abstract class A<T> where T : A<T>
{
public abstract void DoJOB();
}
public class B : A<B>
{
public override void DoJOB()
{
Console.WriteLine("B");
}
}
public class C : A<C>
{
public override void DoJOB()
{
Console.WriteLine("C");
}
}
Works for me. I get the expected
I did something interesting!
So Did I!
when I run it.
Paste this in your Visual Studio and smoke it
using System;
namespace TestDrive
{
class Program
{
static void Main( string[] args )
{
ServiceConsumer x = new ServiceConsumer( new ConcreteService2() ) ;
x.FunnyMethod() ;
return ;
}
}
abstract class AbstractService
{
public abstract void DoSomethingInteresting() ;
}
class ConcreteService1 : AbstractService
{
public override void DoSomethingInteresting()
{
Console.WriteLine("I did something interesting!");
return ;
}
}
class ConcreteService2 : ConcreteService1
{
public override void DoSomethingInteresting()
{
base.DoSomethingInteresting() ;
Console.WriteLine("So Did I!");
return ;
}
}
class ConcreteService : AbstractService
{
public override void DoSomethingInteresting()
{
Console.WriteLine("Not It's my turn to do something interesting!") ;
return ;
}
}
class ServiceConsumer
{
private AbstractService Service ;
public ServiceConsumer( AbstractService serviceInstance )
{
this.Service = serviceInstance ;
return ;
}
public void FunnyMethod()
{
Service.DoSomethingInteresting() ;
return ;
}
}
}
Cheers!
I'm not sure I understand the question, here is my implementation and it works:
namespace CSharpConsole {
public abstract class A {
public abstract void Test();
}
public class B : A {
public override void Test() {
System.Console.WriteLine("B:Test called!");
}
}
public class C : A {
public override void Test() {
System.Console.WriteLine("C:Test called!");
}
}
class Program {
private A _concrete;
public Program(A concrete) {
_concrete = concrete;
}
public void DoTest() {
_concrete.Test();
}
static void Main(string[] args) {
Program pb = new Program(new B());
pb.DoTest();
Program pc = new Program(new C());
pc.DoTest();
}
}
}
Related
Is it possible to use a subset of methods as member methods in different classes in C#?
For instance, I have four functions the void A(), the void B(), the void C() and the void D().
And now I want to have three classes. The first class I would like to have the member methods A, B and C. The second I would like to have the B and D. And the third the A, C and D.
How could I achieve this? Is it possible to achieve this only by using interfaces or are there any other approaches?
If all your three classes should have different implementations for these methods, then classic interfaces are the way to go:
public interface IHaveA {
void A();
}
public interface IHaveB {
void B();
}
public interface IHaveC {
void C();
}
public interface IHaveD {
void D();
}
public class Class1 : IHaveA, IHaveB, IHaveC { // Implement A, B and C here }
public class Class2 : IHaveB, IHaveD { // Implement B and D here }
public class Class3 : IHaveA, IHaveC, IHaveD { // Implement A, C and D here }
If all your classes should have the same implementation of A, B, C and D, you could still use interfaces but you would have to duplicate code:
public static class StaticImplementation {
public void A(IHaveA sender) {
// Do stuff here
}
public void B(IHaveB sender) {
// Do stuff here
}
public void C(IHaveC sender) {
// Do stuff here
}
public void D(IHaveD sender) {
// Do stuff here
}
}
public class Class1 : IHaveA, IHaveB, IHaveC {
public void A() { StaticImplementation.A(this) }
public void B() { StaticImplementation.B(this) }
public void C() { StaticImplementation.C(this) }
}
public class Class2 : IHaveB, IHaveD { // Calls to StaticImplementation for B and D here }
public class Class3 : IHaveA, IHaveC, IHaveD { // Calls to StaticImplementation for A, C and D here }
There is no way to enforce that these three classes have the same implementation of these methods using interfaces, because the primary goal interfaces is to ensure that classes implement methods, specifically with different implementations!
This changes in C# 8.0 and .NET Core 3.0 where you can have default implementations for interface methods, and you could ensure that these implementations do not change by sealing them.
The code would become:
public interface IHaveA {
sealed void A() {
// Implementation here
}
}
public interface IHaveB {
sealed void B() {
// Implementation here
}
}
public interface IHaveC {
sealed void C() {
// Implementation here
}
}
public interface IHaveD {
sealed void D() {
// Implementation here
}
}
public class Class1 : IHaveA, IHaveB, IHaveC { // Nothing to do here }
public class Class2 : IHaveB, IHaveD { // Nothing to do here }
public class Class3 : IHaveA, IHaveC, IHaveD { // Nothing to do here }
using System;
public interface MA {}
public static class MAProvider {
public static void A(this MA obj) { Console.WriteLine("MA"); }
}
public interface MB {}
public static class MBProvider {
public static void B(this MB obj) { Console.WriteLine("MB"); }
}
public interface MC {}
public static class MCProvider {
public static void C(this MC obj) { Console.WriteLine("MC"); }
}
public interface MD {}
public static class MDProvider {
public static void D(this MD obj) { Console.WriteLine("MD"); }
}
public class First : MA, MB, MC {}
public class Second : MB, MD {}
public class Third : MA, MC, MD {}
public static class Program {
public static void Main() {
new First().A();
new First().B();
new First().C();
new Second().B();
new Second().D();
new Third().A();
new Third().C();
new Third().D();
}
}
The only issue which is left is the private members. Since we can not access them inside the extension methods.
Can I call a method from a grandparent class, and if so, how?
I'm trying to do something like this:
class A {
void foo() {
// Do something...
}
}
class B : A {
override void foo() {
// Do something else...
}
}
class C : B {
override void foo() {
// Call A's foo method
// Then do something else
}
}
One approach is to use explicit interface implementation in class A:
This allows you to call A's implementation - both from code within C and from outside C (by casting to IBob first).
using System;
namespace ConsoleApp4
{
interface IBob
{
void foo();
}
class A : IBob
{
void IBob.foo()
{
Console.WriteLine("A");
}
public virtual void foo()
{
((IBob)this).foo();
}
}
class B : A
{
public override void foo()
{
Console.WriteLine("B");
}
}
class C : B
{
public override void foo()
{
Console.WriteLine("C");
// Writes B
base.foo();
// Writes A
((IBob)this).foo();
}
}
public class Program
{
static void Main(string[] args)
{
var sally = new C();
sally.foo(); // A B C
IBob sally2 = sally;
sally2.foo(); // A
Console.ReadLine();
}
}
}
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
}
Consider a namespace defined in .NET framework with a class hierarchy.
namespace OfficialDotnetNS
{
namespace officialNS.Bases
{
public class BaseOfA : IFakeA, IFakeB
{
protected void Driver(Stream stream){ this.DriveFoo(stream); };
protected internal virtual void DriveFoo(Stream stream);
}
}
public abstract class A : officialNS.Bases.BaseofA
{
protected internal override void DriveFoo(Stream stream){ this.Foo(stream); };
protected virtual void Foo(String stream);
}
public class B : A {}
public class C : A {}
public class D : A {}
// and 50+ similar classes derived from A
}
I have a BaseofA object and when I call Driver(stream) it subsequently calls Foo of A and that of suitable derived class.
Now, I want to override Foo() with same code, so all classes derived from A inherit this custom implementation.
One way is to write custom wrapper for each class:
public class CustomB : B
{
protected override void Foo(Stream stream)
{
stream.Position = 12;
base.Foo(stream);
}
}
public class CustomC : C
{
protected override void Foo(Stream stream)
{
stream.Position = 12;
base.Foo(stream);
}
}
public class CustomD : D
{
protected override void Foo(Stream stream)
{
stream.Position = 12;
base.Foo(stream);
}
}
//.. for all 50+ classes
Can we do this using reflection or some other technique without repeating code?
Yes. It's called proxying and it's a technique used by entity framework. There are several ways of achieving this, but IMO the best is the CastleProject DynamicProxy.
For instance (a simplified case, but I think this does what you want):
void Main()
{
var pg = new Castle.DynamicProxy.ProxyGenerator();
var typeA = typeof(A);
var interceptor =
new FooInterceptor(
str => Console.WriteLine("intercepted {0}", str));
IEnumerable<A> objs = Assembly
.GetExecutingAssembly()
.GetTypes()
.Where(t => t.IsSubclassOf(typeA))
.Select(t => (A)(pg.CreateClassProxy(t, interceptor)));
foreach(A a in objs)
{
a.CallFoo("hello world");
}
}
public class A
{
public void CallFoo(string someString){
Foo(someString);
}
protected virtual void Foo(string someString)
{
Console.WriteLine("base Foo {0}", someString);
}
}
public class B : A {}
public class C : A {}
public class D : A {}
public class FooInterceptor : IInterceptor
{
Action<string> interceptorDelegate;
public Interceptor(Action<string> interceptorDelegate)
{
this.interceptorDelegate = interceptorDelegate;
}
public void Intercept(IInvocation invocation)
{
var isFooCall = invocation.Method.Name == "Foo";
if(isFooCall)
{
interceptorDelegate
.Invoke((string)(invocation.Arguments[0]));
}
else
{
invocation.Proceed();
}
}
}
I have the protected variable var1 in the abstract class AbstractModule
I create abstract class AbstractActivity : AbstractModule and use var1 from the parent class AbstractModule
Now I create class MyActivity : AbstractActivity and I want to make var1 not accessible in the MyActivity class.
How can I do it?
(I can create the protected property, but then I have the same problem)
C# does not allow this. But you can shadow the field in your class AbstractActivity by creating one with the same name. Your class MyActivity would then have access to the shadowed field and its value, but not to the field defined in AbstractModule.
public class A
{
protected bool seeMe;
}
public class B : A
{
public B()
{
base.seeMe = false; // this is A.seeMe
}
protected bool seeMe;
}
public class C : B
{
public C()
{
seeMe = true; // this is B.seeMe
}
}
The above example doesn't prevent code from being written that uses the shadow field. This may cause confusion if the programmer is aware of A.seeMe and thinks it is being set. You can force a compile error when B.seeMe is used by decorating it with the Obsolete attribute:
public class B : A
{
public B()
{
base.seeMe = false; // this is A.seeMe
}
[Obsolete("cannot use seeMe", error:true)]
protected bool seeMe;
}
public class C : B
{
public C()
{
seeMe = true; // this will give a compile error
}
}
Same example with above solutions with int value.
I trying to restrict grand parent field in child class with the same name.
public class MyClass
{
protected int myValue = 10;
}
public class MyClass1 : MyClass
{
protected int myValue = 15;
public MyClass1()
{
base.myValue = 25;
this.myValue = 11;
}
}
public class MyClass2 : MyClass1
{
public void print()
{
Console.WriteLine("My Value : " + myValue);//this will print 11
}
}
class Program
{
static void Main(string[] args)
{
MyClass2 myClass2 = new MyClass2();
myClass2.print();
}
}
//Restrict grand parent method in child class using sealed keyword
public class MyClass
{
protected virtual void MyMethod()
{
}
}
public class MyClass1 : MyClass
{
// because of sealed method this method will not going to override in derived class.
sealed override protected void MyMethod()
{
}
}
public class MyClass2 : MyClass1
{
protected override void MyMethod()//this will give compiler error
{
}
}