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();
}
}
}
Related
Abstract Base Class
abstract class Base
{
public abstract void Method<T>(T args) { }
}
Derived Class several of these exist, each with a replacement for T
class Derived : Base
{
public override void Method<int>(int args) { }
}
Now, I know this isn't supported, but I need it because somewhere else in my code
class AnotherBaseClass<T, E>
where E : Base
{
E e; // Will be actually one of the derived classes
T t; // Simple types like string or int
// I want this to work basically
public void Func()
{
e.Method(t);
}
}
this is going on.
What is the easiest solution to this? If I am able to do this, it will save me from writing a lot of code.
If you're fine with making Base a generic class, this is how:
abstract class Base<T>
{
public abstract void Method(T args);
}
class Derived : Base<int>
{
public override void Method(int args) {}
}
class AnotherBaseClass<T, E>
where E : Base<T>
{
E e;
T t;
public void Func()
{
e.Method(t);
}
}
If you need Base to not be generic, you can add this:
abstract class Base
{
public void Method<T>(T args)
{
var genericSelf = this as Base<T>;
genericSelf.Method(args);
}
}
and make Base<T> inherit Base and ensure your concrete classes always derive Base<T> and never Base directly.
I'm not exactly sure what problem you're sovling but under .Net 5 what you have in your question works as is...
abstract class Base
{
public abstract void Method<T>(T args);
}
class Derived : Base
{
public override void Method<T>(T args)
{
Console.Write($"{nameof(Derived)}.Method<{typeof(T)}>({args})");
}
}
class AnotherBaseClass<T, E> where E : Base
{
readonly E e;
readonly T t;
public AnotherBaseClass(T t, E e)
{
this.e = e;
this.t = t;
}
public void Func()
{
e.Method(t);
}
}
Run like so:
static void Main(string[] args)
{
Derived d = new Derived();
var another = new AnotherBaseClass<int,Derived>(5, d);
another.Func();
}
Produces: "Derived.Method<System.Int32>(5)"
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.
I have Generator class that generates objects with different Interfaces with different probabilities. All objects generated by Generator is of type BaseClass. BaseClass is an abstract base class.
Lets say interfaces are I1, I2
I have another class Resolver that has polymorphic method for two interfaces as follows:
Resolve(I1 myObj){//code for I1}
Resolve(I2 myObj){//code for I2}
The main class looks like this:
BaseClass event = Generator.generate(); //event is implements I1 or I2. Not known what interfaces until run time.
Resolver.Resolve(event); //Here i got an error, because event is BaseClass type and not I1 or I2 type.
Is there a way to solve this issue without explicitly check Interface type and cast it to appropriate interface. I came from python background, so statically typed language is new for me.
Consider using dependency injection to allow the event object to call the Resolver itself.
public interface IResolvable
{
void Resolve(Resolver resolver);
}
public interface I1 : IResolvable { //... }
public interface I2 : IResolvable { //... }
public class Resolver
{
public void Resolve(I1 i) { //... }
public void Resolve(I2 i) { //... }
}
public abstract class BaseClass : IResolvable
{
public abstract void Resolve(Resolver resolver);
//...
}
An implementation would look something like:
public class Implementation1 : BaseClass, I1
{
public override void Resolver(Resolver resolver)
{
resolver.Resolve(this);
}
//...
}
And then calling it:
Resolver resolver = new Resolver();
IResolvable evnt = Generator.Generate();
evnt.Resolve(resolver);
We can go a step further and make an interface for Resolver, so we can mock it for unit testing purposes and take full advantage of the DI pattern.
public interface IResolver
{
void Resolve(I1 i) { //... }
void Resolve(I2 i) { //... }
}
Then we change the definition of IResolvable
public interface IResolvable
{
void Resolve(IResolver resolver);
}
Here is some code that demonstrates virtual function approach that doesn't need casting.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication3
{
interface IBase
{
void Function();
}
class BaseClass : IBase
{
public virtual void Function()
{
}
}
interface I1: IBase
{
}
interface I2 : IBase
{
}
class C1: BaseClass, I1
{
public override void Function()
{
Console.WriteLine("Hello from C1");
}
}
class C2 : BaseClass, I1
{
public override void Function()
{
Console.WriteLine("Hello from C2 !!!");
}
}
static class Generator
{
public static BaseClass generateC1()
{
return new C1();
}
public static BaseClass generateC2()
{
return new C2();
}
}
class Program
{
static void Main(string[] args)
{
BaseClass b1 = Generator.generateC1();
b1.Function();
Console.WriteLine("-------");
BaseClass b2 = Generator.generateC2();
b2.Function();
Console.WriteLine("End!");
}
}
}
EDIT I adjusted my answer because I did not understand the question correctly the first time.
I think that you can not achieve exactly what you would like to without using casts. As far as I understand as soon as you reference the object you get from Generator.generate() by its base type it is not possible to access the object by its specialized type again without casting it.
I can think of two alternatives which might be interesting for you. One is using C# 7 pattern matching (which is a bit like using casts) and the other is using dynamic.
Pattern matching
using System;
namespace EventREsolver
{
public interface IEvent { }
public class Event1 : IEvent { }
public class Event2 : IEvent { }
public class Resolver
{
public void Resolve(IEvent theEvent)
{
switch (theEvent)
{
case Event1 e1: Resolve(e1); break;
case Event2 e2: Resolve(e2); break;
default: throw new ArgumentException("not a recognized type", nameof(theEvent));
}
}
private void Resolve(Event1 theEvent)
{
Console.WriteLine("Resolve I1");
}
private void Resolve(Event2 theEvent)
{
Console.WriteLine("Resolve I2");
}
}
public class Generator
{
int state = 0;
public IEvent Generate()
{
if (state == 0)
{
state++;
return new Event1();
}
return new Event2();
}
}
class Program
{
static void Main(string[] args)
{
var generator = new Generator();
var event1 = generator.Generate();
var event2 = generator.Generate();
var resolver = new Resolver();
resolver.Resolve(event1);
resolver.Resolve(event2);
Console.ReadKey();
}
}
}
Dynamic
using System;
namespace EventREsolver
{
public interface IEvent { }
public class Event1 : IEvent { }
public class Event2 : IEvent { }
public class Resolver
{
public void Resolve(Event1 theEvent)
{
Console.WriteLine("Resolve I1");
}
public void Resolve(Event2 theEvent)
{
Console.WriteLine("Resolve I2");
}
}
public class Generator
{
int state = 0;
public IEvent Generate()
{
if (state == 0)
{
state++;
return new Event1();
}
return new Event2();
}
}
class Program
{
static void Main(string[] args)
{
var generator = new Generator();
dynamic event1 = generator.Generate();
dynamic event2 = generator.Generate();
var resolver = new Resolver();
resolver.Resolve(event1);
resolver.Resolve(event2);
Console.ReadKey();
}
}
}
The code is simple enough to understand I hope.
I'm trying to use an interface type IColor in order to pass color objects to the ColorManager. I then want the ColorManager to pass this object to the IColor object as its own type, so the method overloads gets called.
However, it seems since it is being passed as the IColor type, C# will not implicity cast it into its complete type as either a BlueColor or GreenColor.
I hope this makes some sense to somebody on what I want to achieve. Is this possible in C#?
[Solution]
http://msdn.microsoft.com/en-us/library/dd264736.aspx
Overload Resolution with Arguments of Type dynamic
My code so far:
using System;
using System.Collections.Generic;
using System.Windows.Forms;
using System.IO;
namespace Example
{
public interface IColor
{
void CatchColor(IColor c);
}
public class BlueColor : IColor
{
public void CatchColor(IColor c)
{
}
}
public class GreenColor : IColor
{
public void CatchColor(BlueColor c)
{
Console.WriteLine("CAUGHT BLUE!");
}
public void CatchColor(GreenColor c)
{
Console.WriteLine("CAUGHT GREEN!");
}
public void CatchColor(IColor c)
{
Console.WriteLine("CAUGHT SOME COLOR!");
}
}
public class ColorManager
{
public void PassColor(IColor c)
{
// Don't use static type-checking
// Problem solved
dynamic AnyColor = c;
AnyColor.CatchColor(AnyColor);
}
public static void Main()
{
GreenColor G = new GreenColor();
new ColorManager().PassColor(G);
Console.ReadLine();
return;
}
}
}
One possiblity to tell the ColorManager class to use the correct type of the passed object is to use an abstract class, that already implements the CatchColor:
public abstract class IColor
{
// override in every class
public abstract void PrintColor();
// has the correct type passed with the interface
public void CatchColor(IColor c)
{
c.PrintColor();
}
}
Then the sub classes need to implement only PrintColor with the correct color:
public class BlueColor : IColor
{
public override void PrintColor()
{
Console.WriteLine("BLUE!");
}
}
public class GreenColor : IColor
{
public override void PrintColor()
{
Console.WriteLine("GREEN!");
}
}
The manager is the same:
public class ColorManager
{
public void PassColor(IColor c)
{
c.CatchColor(c);
}
}
It can be used like this:
GreenColor G = new GreenColor();
var cm = new ColorManager();
cm.PassColor(G);
cm.PassColor(new BlueColor());
The outputs is:
GREEN!
BLUE!
What you want is late method binding.
The downside to this is you have to add methods for each new type of color. The upside is you don't have to maintain a case statement or conditional logic.
See here for more detail:
Early and late binding
Edit: Here is a working example of this type of late-binding.
class Program {
static void Main(string[] args) {
//Declare instances
BaseClass myClass = new Class2();
BaseClass otherClass = new Class1();
//Invoke the action method which will match based on the BaseClass type
Action(myClass);
Action(otherClass);
Console.ReadLine();
}
public static void Action(BaseClass classType) {
//Remove the compile-time type so the runtime can select the method based on signature
dynamic aClass = classType;
ServiceMethod(aClass);
}
public static void ServiceMethod(dynamic input) {
Methods(input);
}
public static void Methods(Class1 classType) {
Console.WriteLine("Class1");
Debug.WriteLine("Class1");
}
public static void Methods(Class2 classtype) {
Console.WriteLine("Class2");
Debug.WriteLine("Class2");
}
public static void Methods(Class3 classType) {
Console.WriteLine("Class3");
Debug.WriteLine("Class3");
}
}
public abstract class BaseClass { //This could also be an interface
public Guid Id { get; set; }
public string Name { get; set; }
}
public class Class1 : BaseClass {
}
public class Class2 : BaseClass{
}
public class Class3 : BaseClass {
}
So you want something like:
public void CatchColor(Color c)
{
if (c is BlueColor)
CatchColor(c as BlueColor);
if (c is GreenColor)
CatchColor(c as GreenColor);
}
?
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();
}
}
}