using generic method in abstract class with child class result - c#

I'm working to DRY some code up and I'm running into the following situation. I've reworked the code to provide a better example of the scenario.
namespace SourceCode
{
public interface IFactory
{
public baseClass GenerateClass();
public bool IsUsable();
}
public abstract baseClass
{
...
}
public AClass:baseClass
{
...
}
public class FactoryA:IFactory
{
public baseClass GenerateClass()
{
return new AClass();
}
public bool IsUsable(){
{
return true if some condition;
}
}
public BClass:baseClass
{
...
}
public class FactoryB:IFactory
{
public baseClass GenerateClass()
{
return new BClass();
}
public bool IsUsable(){
{
return true if some condition;
}
}
public static class FactoryProvider
{
List<IFactory> factories
static FactoryProvider()
{
factories.Add(new FactoryA());
factories.Add(new FactoryB());
}
static List<baseClass> GetClasses()
{
return (from f in factories where f.IsUsable() select f).ToList();
}
}
}
namespace SourceCode.Tests
{
public class baseTests
{
public T GenericMethod<T>(){...}
}
public class ClassATests:baseTests
{
public void Test1()
{
... generic used in a method provided by the base class
}
}
public class ClassBTests:baseTests
{
public void Test1()
{
... generic used in a method provided by the base class
}
}
}
So the problem in my tests is that there are tests that will have to happen for every child class.
UPDATE=======================
I was able to solve my issue by doing the following.
namespace SourceCode.Tests
{
public class baseTests<I> where I: baseClass
{
public void Test1()
{
var result = GenericMethod<I>();
// The generic method will use ClassA for ClassATests
// and ClassB for ClassBTests
}
public T GenericMethod<T>(){...}
}
public class ClassATests:baseTests<ClassA>
{
}
public class ClassBTests:baseTests<ClassB>
{
}
}

Making your current A class generic could solve problems:
abstract class A
{
// protected members...
protected abstract A InternalGetData(List<A> src);
public void SharedMethodHappensAlways()
{
List<A> src = new List<A>();
var childResult = InternalGetData(src);
}
}
abstract class A<T> : A
where T: A
{
public T GetData(List<A> src)
{
return src.OfType<T>().FirstOrDefault();
}
protected override A InternalGetData(List<A> src)
{
return GetData(src);
}
}
class B : A<B>
{
}
class C : A<C>
{
}
Sample usage:
List<A> src = new List<A>() { new B(), new C() };
B b = new B();
b.SharedMethodHappensAlways();
B firstB = b.GetData(src); // returns first instance of B
C firstC = new C().GetData(src);

Related

c# Factory for concrete implementation of generic base class

I have a Base class which is generic.
I have a concrete class which implements the base class.
How would I create a factory class/method for delivering different types of concrete classes?
Here an example:
public class ReceiverBase<T>
where T : IInterpreter
{ ... }
public class SpecialReceiver : ReceiverBase<OwnInterpreter> { ... }
public class ReceiverFactory<T>
where T : ReceiverBase<IInterpreter>, new()
public T Create(string type) {
switch(type) {
default:
return new SpecialReceiver();
}
}
}
The problem is that ReceiverBase seems not to be possible because the compiler only wants classes as Constraints, not interfaces.
And the second problem is that I cannot convert SpecialReceiver to T.
So is there a way to get this working?
=== EDIT: Added example according to first answer ===
public interface IInterpreter
{
}
public class OwnInterpreter : IInterpreter
{
public void Dispose()
{
throw new NotImplementedException();
}
public void DoSomething() { }
}
public abstract class ReceiverBase<T>
where T : IInterpreter
{
public T MyReceiver { get; set; }
internal abstract void Start();
}
public class SpecialReceiver<T> : ReceiverBase<T>
where T : IInterpreter, new()
{
public void CheckSomething()
{
MyReceiver.DoSomething();
}
internal override void Start()
{
MyReceiver = new T();
}
}
public class ReceiverFactory<T>
where T : IInterpreter, new()
{
public static ReceiverBase<T> Create(string type)
{
switch (type)
{
default:
return new SpecialReceiver<T>();
}
}
}
The Problem is: MyReceiver.DoSomething(); will not work.
Additionally I would have to call the factory like this: ReceiverFactory<OwnInterpreter>.Create(""); I'd like to have it that way: ReceiverFactory.Create("SpecialReceiver");
You can use generic method in your factory:
class Program
{
static void Main(string[] args)
{
var own = ReceiverFactory.Create<OwnInterpreter>();
var other = ReceiverFactory.Create<OtherInterpreter>();
own.Start();
other.Start();
Console.ReadLine();
}
}
interface IInterpreter
{
void DoSomething();
}
class OwnInterpreter : IInterpreter
{
public void DoSomething() { Console.WriteLine("Own"); }
}
class OtherInterpreter : IInterpreter
{
public void DoSomething() { Console.WriteLine("Other"); }
}
abstract class ReceiverBase<T> where T: IInterpreter, new()
{
public T Interpreter { get; set; }
public ReceiverBase()
{
Interpreter = new T();
}
public void Start()
{
Interpreter.DoSomething();
}
}
class SpecialReceiver : ReceiverBase<OwnInterpreter> { }
class OtherReceiver : ReceiverBase<OtherInterpreter> { }
static class ReceiverFactory
{
private static Dictionary<string, object> factories = new Dictionary<string, object>();
static ReceiverFactory()
{
RegisterFactory(() => new SpecialReceiver());
RegisterFactory(() => new OtherReceiver());
}
public static void RegisterFactory<T>(Func<ReceiverBase<T>> factory) where T : IInterpreter, new()
{
factories.Add(typeof(T).FullName, factory);
}
public static ReceiverBase<T> Create<T>() where T : IInterpreter, new()
{
var type = typeof(T);
return ((Func<ReceiverBase<T>>)factories[type.FullName]).Invoke();
}
}
In fact, you do not need "new()" constraint here, since you use factories.
I suggest you to change your code to:
public class ReceiverBase<T> where T : IInterpreter
{
}
public interface IInterpreter
{
}
public class SpecialReceiver<T> : ReceiverBase<T>
where T : IInterpreter
{
}
public class OwnInterpreter : IInterpreter
{
}
public class ReceiverFactory<T> where T : IInterpreter, new()
{
public ReceiverBase<T> Create(string type)
{
switch (type)
{
default:
return new SpecialReceiver<T>();
}
}
}
The reason why you cannot just return T in your case is, that there is no implicit conversion between SpecialReceiver and ReceiverBase<IInterpreter>.
I was able to find a solution which suits my needs.
I've added another interface IReciver which defines the properties and members I really need. The factory method returns IReceiver so I can omit all binding issues whith generics. Sometimes it is just that easy. :)
public interface IInterpreter { }
public interface IReceiver
{
bool Enabled { get; set; }
}
public class OwnInterpreter : IInterpreter
{
public void DoSomething() { }
}
public abstract class ReceiverBase<T> : IReceiver
where T : IInterpreter, new()
{
public T MyReceiver { get; set; }
internal abstract void Start();
private bool _isEnabled;
public bool Enabled { get { return _isEnabled; } set { _isEnabled = value; OnEnable(value); } }
internal abstract void OnEnable(bool isEnabled);
protected ReceiverBase()
{
MyReceiver = new T();
}
}
public class SpecialReceiver : ReceiverBase<OwnInterpreter>
{
public void CheckSomething()
{
MyReceiver.DoSomething();
}
internal override void Start()
{
// just for testing puropses
MyReceiver = new OwnInterpreter();
}
internal override void OnEnable(bool isEnabled)
{
MyReceiver = isEnabled ? new OwnInterpreter() : null;
}
}
public class ReceiverFactory
{
public static IReceiver Create(string type)
{
switch (type)
{
default:
return new SpecialReceiver();
}
}
}
public class Program
{
[STAThread]
public static void Main()
{
ReceiverFactory.Create("");
}
}

Method Override with some condition in Console application

I am creating one console application. I have one class in which I wrote some methods. Now I want to override some methods of that class in a different class. But this should be override only if condition satisfied.
For example,
public partial Class MainClass
{
public string GetPath()
{
string temp = Method1();
return temp;
}
protected virtual string Method1()
{
//logic
}
}
If some condition satisfied then only overridden method should be called
public partial class ChildClass : MainCLass
{
public override void Method1()
{
//MY Logic
}
}
How can I achieve this? Is it possible to do so?
In ChildClass you can do something like this:
public partial class ChildClass : MainCLass
{
public override void Method1()
{
if(condition)
{
base.Method1();
return;
}
//YOUR LOGIC
}
}
EXAMPLE
public class A
{
public virtual void MethodA()
{
Console.WriteLine("A:MethodA");
}
}
public class B : A
{
public bool CallBase { get; set; }
public B()
{
CallBase = false;
}
public override void MethodA()
{
if (CallBase)
{
base.MethodA();
return;;
}
Console.WriteLine("B:MethodA");
}
}
class Program
{
static void Main(string[] args)
{
A a = new A();
B b = new B();
a.MethodA();
b.MethodA();
b.CallBase = true;
b.MethodA();
A c = new B();
c.MethodA();
A d = new B(true);
d.MethodA();
Console.ReadKey();
}
}
Output
A:MethodA
B:MethodA
A:MethodA
B:MethodA
A:MethodA

Access a class method using another class instance?

I have a requirement of dynamically invoke a class and use the methods of that class.
public class A
{
public void test()
{
}
}
public Class B
{
public void test()
{
}
}
class object intermediate
{
//here will decide which class to be invoked
//return the invoked class instance
}
class clientclass
{
intermedidate client=new intermediate();
}
So can i access the methods of the invoked class, in the instance client.
Im using Framework 3.5. If child class inherited from the intermediate class, is it possible to achieve this? I dont want reflection here.
You can do like follows (not verified)
interface I
{
}
class A :I
{
}
Class B:I
{
}
class intermediate
{
public I GetInstance(int i)
{
if(i==1)
return new A();
else
return new B();
}
}
class clientclass
{
I client=new intermediate().GetInstance(1);
}
Try this
public interface IClassA
{
void Method();
}
public class ClassA : IClassA
{
public void Method()
{
}
}
public static class ObjectInjector
{
public static T GetObject<T>()
{
object objReturn = null;
if(typeof(T) == typeof(IClassA))
{
objReturn = new ClassA();
}
return (T)objReturn;
}
}
public class ClientClass
{
static void Main(string[] args)
{
IClassA objA = ObjectInjector.GetObject<IClassA>();
objA.Method();
}
}
You could try and do the interface implementation as the Șhȇkhaṝ has above.
You could also use an abstract class if you require initial processing before class A or B's test method is invoked.
Here is an example of a console app that demonstrates this:
public abstract class MainClass
{
public virtual void test()
{
Console.WriteLine("This is the abstract class");
}
}
public class A : MainClass
{
public override void test()
{
base.test();
Console.WriteLine("Class A");
}
}
public class B : MainClass
{
public override void test()
{
base.test();
Console.WriteLine("Class B");
}
}
public class Intermediate
{
public MainClass CreateInstance(string name)
{
if (name.ToUpper() == "A")
{
return new A();
}
else
{
return new B();
};
}
}
class Program
{
static void Main(string[] args)
{
Intermediate intermediate = new Intermediate();
var client = intermediate.CreateInstance("B");
client.test();
Console.ReadLine();
}
}

Getting current class name including parent class name?

If I have a class B and C which inherits from A, is there something simpler than using StackFrame's GetFileName() (then parse out the ClassName.cs string)?
If I use this.GetType().Name, it won't return "A" when the code is executing in the parent class.
Sample Code
namespace StackOverflow.Demos
{
class Program
{
public static void Main(string[] args)
{
B myClass = new C();
string containingClassName = myClass.GetContainingClassName();
Console.WriteLine(containingClassName); //should output StackOverflow.Demos.B
Console.ReadKey();
}
}
public class A { public A() { } }
public class B : A { public B() { } }
public class C : B { public C() { } }
}
var yourType = GetType();
var baseType = yourType.BaseType;
or alternatively:
var currentTypeName = new StackFrame(1, false).GetMethod().DeclaringType.Name;
I use myObject.GetType().FullName which returns the fully qualified name of the class. For your scenario, you could use myObject.GetType().BaseType.FullName
Option 1 :: Getting the "container" class:
/**CODE**/
public static void Main(string[] args)
{
B c = new C();
Test(c);
Console.ReadKey();
}
public static void Test(A a) { Console.WriteLine(typeof(A).ToString()); }
public static void Test(B b) { Console.WriteLine(typeof(B).ToString()); }
public static void Test(C c) { Console.WriteLine(typeof(C).ToString()); }
/**OUTPUT**/
StackOverflow.Demos.B
Option 2 :: Getting the "container" class:
/**CODE**/
class Program
{
public static void Main(string[] args)
{
B myClass = new C();
Console.WriteLine(myClass.GetContainerType()); //should output StackOverflow.Demos.B
Console.ReadKey();
}
}
public interface IGetContainerType
{
Type GetContainerType();
}
public class A: IGetContainerType
{
public A() { }
public Type GetContainerType()
{
return typeof(A);
}
}
public class B : A
{
public B() { }
public new Type GetContainerType()
{
return typeof(B);
}
}
public class C : B
{
public C() { }
public new Type GetContainerType()
{
return typeof(C);
}
}
/**OUTPUT**/
StackOverflow.Demos.B
Answer to similar but different question; Getting the instance class / full hierarchy:
/**CODE**/
class Program
{
public static void Main(string[] args)
{
C c = new C();
Type myType = c.GetType();
while(myType != null)
{
Console.WriteLine(myType);
myType = myType.BaseType;
}
Console.ReadKey();
}
}
/**OUTPUT**/
StackOverflow.Demos.C
StackOverflow.Demos.B
StackOverflow.Demos.A
System.Object
When you say GetType(), or equivalently this.GetType(), you get the actual type of the class. For example
class A
{
public void Test()
{
Console.WriteLine(GetType().Name);
}
}
class B : A
{
}
and later:
var myB = new B();
myB.Test(); // writes B to the console
I guess that's what polymorphism is all about.
If you want always A, no polymorphism, simply say:
class A
{
public void Test()
{
Console.WriteLine(typeof(A).Name);
}
}
class B : A
{
}

C# Base and 2 Derived Classes initialization

So I only want to use one class Object for all of my functions but I do not want to directly use that class instead I need to access the members of the derived classes.
Take this example:
class A {
public A() {
}
public void DoSomething() { }
}
class B : A {
public B() {
}
public void DoSomethingBetter() { }
}
class C : A {
public C() {
}
public void DoSomethingBest() { }
}
class Runner {
public static void Main(String[] args) {
A objB = new B();
objB.DoSomethingBetter(); //Won't compile
A objC = new C();
objC.DoSomethingBest(); //Won't compile
}
}
I don't want to initialize them as B objB = new B(), that is not the purpose and I already know that that could be a solution. I need to just use the parent class for this.
Thanks
If you're going to declare the methods with different names, you're going to have to instantiate the explicit type in your code.
If the methods all perform the same function but in different manners, you should override the method from the base class rather than re-implement it with a different name.
public class A
{
public virtual void DoSomething()
{
// some implementation
}
}
public class B : A
{
public override void DoSomething()
{
// body of DoSomethingBetter
}
}
public class C : A
{
public override void DoSomething()
{
// body of DomSomethingBest
}
}
The body of your application would simplify to:
A b = new B();
A c = new C();
b.DoSomething() // uses logic of DoSomethingBetter
c.DoSomething() // uses logic of DoSomethingBest
Not 100% sure what you're trying to accomplish, but this is an option if for some reason you don't want to override as others suggested.
class A {
public A() {
}
public void DoSomething() { }
}
class B : A {
public B() {
}
public void DoSomethingBetter() { }
}
class C : A {
public C() {
}
public void DoSomethingBest() { }
}
class Runner {
public static void Main(String[] args) {
A objB = new B();
if (objB is B)
((B)objB).DoSomethingBetter();
A objC = new C();
if (objC is C)
((C)objC).DoSomethingBest();
}
}
EDIT: A more efficient way to do this is as follows (it will run 2 casts instead of 4):
class A {
public A() {
}
public void DoSomething() { }
}
class B : A {
public B() {
}
public void DoSomethingBetter() { }
}
class C : A {
public C() {
}
public void DoSomethingBest() { }
}
class Runner {
public static void Main(String[] args) {
A objB = new B();
B objAB = objB as B;
if (objAB != null)
objAB.DoSomethingBetter();
A objC = new C();
C objAC = objC AS C;
if (objAC != null)
objAC.DoSomethingBest();
}
}
Is it perhaps overriding that you are looking for?
You can make the A class abstract, and methods in it also. Then put the actual implementation in the derived classes:
abstract class A {
public A() {
}
public abstract void DoSomething() { }
}
class B : A {
public B() {
}
public override void DoSomething() { }
}
class C : A {
public C() {
}
public override void DoSomething() { }
}
class Runner {
public static void Main(String[] args) {
A objB = new B();
objB.DoSomething(); // Uses the B implementation
A objC = new C();
objC.DoSomething(); // Uses the C implementation
}
}
Without seeing your actual code I'm inclined to agree with everyone else who says you should really try again to fix your problem using simple overrides.
Nevertheless, I had some fun toying around with this problem and managed to write a solution that does no casting.
Enjoy!
public class BattlePlan
{
public Action<Puppy> ExecutePuppyAttack { get; set; }
public Action<Pigeon> ExecutePigeonAttack { get; set; }
}
public abstract class Animal
{
public abstract void Attack(BattlePlan battlePlan);
}
public class Puppy : Animal
{
public void Bite(bool barkFirst)
{
// optionally bark at the intruder,
// then bite as deeply as needed.
}
public override void Attack(BattlePlan battlePlan)
{
battlePlan.ExecutePuppyAttack(this);
}
}
public class Pigeon : Animal
{
public void Bombard(int altitude)
{
// ewww. nuff said.
}
public override void Attack(BattlePlan battlePlan)
{
battlePlan.ExecutePigeonAttack(this);
}
}
public class EvilMasterMind
{
private bool _puppiesMustBark = true;
private int _pigeonAltitude = 100;
public void Attack()
{
var battlePlan = new BattlePlan
{
ExecutePuppyAttack = e => e.Bite(_puppiesMustBark),
ExecutePigeonAttack = e => e.Bombard(_pigeonAltitude)
};
var animals = new List<Animal>
{
new Puppy(),
new Pigeon()
};
foreach (var animal in animals)
{
animal.Attack(battlePlan);
}
}
}

Categories