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)"
Related
is there a keyword for the question "?" mark below or a way to achieve the same effect without using templates?
abstract class A
{
public abstract void Attach(? x);
}
class B : A
{
public override void Attach(B b) {}
}
class C : A
{
public override void Attach(C c) {}
}
so that:
var b1 = new B();
var b2 = new B();
var c = new C();
b1.Attach(b2);
b1.Attach(c); // should not compile
EDIT:
with templates i mean type parameters such as Attach<T>(T x, T y) // if we ignore that the example takes 1 argument
Annoyingly, no. The closest you can get is:
abstract class A<T> where T : A<T>
{
public abstract void Attach(T x);
}
class B : A<B>
{
public override void Attach(B b) { }
}
class C : A<C>
{
public override void Attach(C c) { }
}
This doesn't however stop someone from writing:
class D : A<B>
{
...
}
If you want to avoid this, you need a runtime check for this.GetType() == typeof(T) or similar in A's constructor.
You can make A Generic like so:
abstract class A<T> where T : A<T>
{
public abstract void Attach(T x);
}
class B : A<B>
{
public override void Attach(B b) {}
}
class C : A<C>
{
public override void Attach(C c) {}
}
Than the following does not comile
b1.Attach(c); // should not compile
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 need to return "this" or the subclass instance from the superclass.
interface IA
{
IA Format();
void Print();
}
interface IB
{
IA Format();
void Print();
void PrintB();
}
abstract class A : IA
{
protected bool isFormated;
public IA Format()
{
isFormated = true;
return this;
}
virtual public void Print()
{
Console.WriteLine("this is A");
}
}
class B : A, IB
{
override public void Print()
{
Console.WriteLine("this is B");
}
public void PrintB()
{
if (isFormated)
{
Console.WriteLine("this is formated B");
}
else
{
Console.WriteLine("this is B");
}
}
}
class Program
{
static void Main(string[] args)
{
var x = new B();
x.Format().PrintB();
}
}
I have two Classes, class A is superclass and class B is the subclass inherited from A.
those two classes implementing Interface A and B.
I need to call 'x.Format().PrintB();' just to format the string.
in other words, I need to return the same object in Format() function and based on the changes in the Format() I need to change the PrintB behavior.
so if I created new Class D and inherits A I want to Implement PrintD with different behavior based on isFormated as well.
I made A as a generic class take type T and I returned this as T
interface IA<T> where T : class
{
T Format { get; }
void Print();
}
abstract class A<T> : IA<T> where T : class
{
protected bool isFormated;
public T Format
{
get
{
isFormated = true;
return this as T;
}
}
virtual public void Print()
{
Console.WriteLine("this is A");
}
}
interface IB
{
void Print();
void PrintB();
}
class B : A<B>, IB
{
override public void Print()
{
Console.WriteLine("this is B");
}
public void PrintB()
{
if (isFormated)
{
Console.WriteLine("this is formated B");
}
else
{
Console.WriteLine("this is B");
}
}
}
class Program
{
static void Main(string[] args)
{
var x = new B();
x.Format.PrintB();
}
}
When you call x.Next(), it returns an instance of something that implements IA. That could be A, B, or any other class that implements IA, but because it returns IA, other classes don't know what the concrete type is. That's usually intentional. If other classes don't know what the implementation of IA is then you can replace one with another.
However, since Next returns an IA, the only way you can call PrintB is if IA has a PrintB method, like this:
public interface IA
{
void PrintB();
}
If A implements IA then it must have a PrintB method. But because it's an abstract class the method can be abstract. That means A doesn't really implement the method. A non-abstract class that inherits from A would be required to implement it.
That would look like this:
abstract class A : IA
{
public IA Next()
{
return this;
}
virtual public void Print()
{
Console.WriteLine("this is A");
}
public abstract void PrintB();
}
PrintB doesn't have to be abstract. A could implement it. It could be virtual and other classes could override it. Or it could be neither abstract nor virtual, and other classes couldn't override it.
Now, when you declare B : A, the compiler will require B to implement PrintB.
Then you can call Next().PrintB() because Next() returns IA and IA has a PrintB method.
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 3 interfaces with 2 methods each doing the same job.
Interface A
{
Void M1()
Void M2()
}
Interface B
{
Void M1()
Void M2()
}
Interface C
{
Void M1()
Void M2()
}
Now, There are 3 classes implementing each of these interfaces.
Public Class A1:A
{
Public void M1()
{
}
Public void M2()
{
}
}
Public Class B1:B
{
Public void M1()
{
}
Public void M2()
{
}
}
Public Class C1:C
{
Public void M1()
{
}
Public void M2()
{
}
}
Functionality of M1 and M2 is exactly same in 3 classes. Interfaces are a part of library, I cannot change the interface and also cannot declare a new interface.
I want to refactor this code so that this duplication can be removed. I thought of creating a common class containing this functionality and then calling common class from each of these classes.
Please suggest.
It sounds like you should declare your own interface, and then create an adapter - or possibly multiple adapters. For example:
public interface IUnified
{
void M1();
void M2();
}
public class UnifiedAdapter : IUnified
{
private Action m1;
private Action m2;
public UnifiedAdapter(A a)
{
m1 = () => a.M1();
m2 = () => a.M2();
}
public UnifiedAdapter(B b)
{
m1 = () => b.M1();
m2 = () => b.M2();
}
public UnifiedAdapter(C c)
{
m1 = () => c.M1();
m2 = () => c.M2();
}
public M1()
{
m1();
}
public M2()
{
m2();
}
}
(This uses delegates to avoid having to create multiple adapter classes. The best approach depends on your exact situation.)
public abstract class XX : X
{
public void M1()
{
}
public void M2()
{
}
}
public interface X : A, B, C
{
}
Given the odd restrictions (and if you can I really suggest trying to get the interfaces changed) I think this is the best you can do:
public class Base : A, B, C {
public void M1(){}
public void M2(){}
}
Now inherit from Base in A1, B1 and C1.
However, if an A cannot, or should not, also be a B then this pattern won't work.
Therefore you would indeed have to go for the next best thing - a common base with the common functionality:
public class Base {
protected void M1Impl() { /* put your common implementation in here */ }
protected void M2Impl() { /* put your common implementation in here */ }
}
As the comments say - put the duplicated M1 and M2 code in the M1Impl and M2Impl methods here.
Now you can reuse this base for A, B and C implementations:
//common base for any implementation of A
//repeat for B and C
public class A1Base : Base, A
{
public void M1() { M1Impl(); }
public void M2() { M2Impl(); }
}
public class A1 : A1Base { }
I've worked on the basis here that you might have many implementations of A or B or whatever, and therefore you want a common starting point for each of those. If that's not the case, then you can do away with A1Base and simply call it A1.
public class BaseClass : A, B, C
{
public void M1()
{
}
public void M2()
{
}
}
Then just inherit from BaseClass:
public class A1 : BaseClass
{
}
public class B1 : BaseClass
{
}
public class C1 : BaseClass
{
}
A1 still will implement interface A. B1 will implement interface B. Same with C1. So, all your existing code will remain working:
A a = new A1();
a.M1();
If you only want to avoid to duplicate the implementation of those methods, then your initial approach is correct.
public class HelperClass
{
public static void M1()
{
// implementation code
}
public static void M2()
{
// implementation code
}
}
public class A1:A
{
public void M1()
{
HelperClass.M1();
}
public void M2()
{
HelperClass.M2();
}
}
public class B1:B
{
public void M1()
{
HelperClass.M1();
}
public void M2()
{
HelperClass.M2();
}
}
public class C1:C
{
public void M1()
{
HelperClass.M1();
}
public void M2()
{
HelperClass.M2();
}
}
Even if interfaces A, B, and C have the same methods, they may have different semantics and may make sense to have them as separate interfaces. That is, making a class implement A, may mean something different than implementing B, even if their methods have the same signatures.
Adding additional interfaces or common base classes is overkill and adds unneeded coupling. As I said before, if you only need to avoid duplicating the methods' implementation, a helper class is the easiest and cleanest solution.