I know that the title may be confusing (or even misleading), but I'm planning to create an interface which is generic, and it should implement a method involving a generic parameter.
When implemented in class AFirst, it should have a method MyMethod<A>() that returns the type A, and when implemented in class BFirst, it should have a method MyMethod<B>() that returns type B. I need this functionality as there is an inheritance relationship between A and B (and MANY others) and I need a generic method that I can call with any of the base classes.
If it was confusing, have a look at what I want to do:
Consider B derives from A.
Consider AFirst and BFirst implement IMyInterface<A> and IMyInterface<B> respectively:
BFirst mySecondObj = new BFirst();
A myA = BFirst.MyMethod<A>();
B myB = BFirst.MyMethod<B>();
I need access to the MyMethod templates for the base classes to, so when I instantiate the BFirst instance, I can call either MyMethod for A or B. I'm building a template system and think these AFirst and BFirst are the templates, and MyMethod acts like a factory method. I will have a big hierarchy, and the project needs to be extensible by deriving even more classes from my base class A, so I can't just create seperate interfaces or methods for each of them.
I tried this:
interface IMyInterface<T> where T : A
{
T GetNewInstance<T>();
}
and I tried to implement this way, but I'm getting it as created like this when I click implement:
class AFirst : IMyInterface<A>
{
public T GetNewInstance<T>()
{
throw new NotImplementedException();
}
}
Didn't make sense to me in the way that I've specified the T type to be A, but it still implements as T. For example, it will go like this (below is how I want it to happen)
class AFirst : IMyInterface<A>
{
public A GetNewInstance<A>()
{
throw new NotImplementedException();
}
}
class BFirst : AFirst, IMyInterface<B>
{
public B GetNewInstance<B>()
{
throw new NotImplementedException();
}
}
and from outer code, call the sample as in the beginning of my question:
BFirst myBFirst = new BFirst();
A a = BFirst.GetNewInstance<A>(); //calls AFirst's method and returns A
B b = BFirst.GetNewInstance<B>(); //calls BFirst's method and returns B
How is this possible?
Thanks,
Can.
In your generic interface you define a generic method. I think that's where the confusion is. It should be a normal method that returns your generic type. I.e.
interface IMyInterface<T> where T : A
{
T GetNewInstance();
}
This will get implemented as
class AFirst : IMyInterface<A>
{
public A GetNewInstance()
{
throw new NotImplementedException();
}
}
which I'm guessing is what you want.
You are possibly over complicating this. You could consider a Template pattern. The base class is abstract and defines an overridable method. Classes inheriting from this base class then provide implementations of this method.
You can still use generics and an interface but this pattern is probably the basis you would need to start from.
Edit:
public abstract class ABase<T>
{
public abstract T MyMethod();
}
public class A : ABase<A>
{
public override A MyMethod()
{
throw new NotImplementedException();
}
}
public class B : A
{
}
And to implement an interface, this would be
public interface IHasMethod<T>
{
T MyMethod();
}
public abstract class ABase<T> : IHasMethod<T> ...
Related
I am certain that I simply do not know the name for what I am trying to do, otherwise my googling would be more successful. I currently only find results pertaining to interfaces with same named methods.
I have a few classes that inherit from a common base class and some implement an interface. I have methods accepting the base class or the interface as a parameter. I cannot compile since this causes ambiguity with the error
the call is ambiguous between the following methods or properties: DoThings(IQueryable<A>) and DoThings(IQueryable<B>)` on the call in ConcreteExecutionClass.
Furthermore, generics won't work because type constraints on generics do not make a unique method signature.
Is there a way (or an acceptable pattern) to force the execution to a specific method based on parameter types?
public abstract class A {
// some properties
}
public class ConcreteA : A {
// full implementation
}
public interface B {
// a property
}
public class ConcreteAB : A, B {
// full implementation
}
public abstract class ExecutionClass {
public IQueryable<A> DoThings(IQueryable<A> content){
return A.method().AsQueryable();
}
public IQueryable<B> DoThings(IQueryable<B> content){
return B.interfaceRequiredMethod().method().AsQueryable();
}
}
public class ConcreteExecutionClass : ExecutionClass {
public void Program(){
var objectList = new List<ConcreteAB>{/*....*/};
DoThings(objectList);
}
}
Each of the concrete classes has a class managing linq queries on lists of objects, which each call DoThings(). The goal is to keep the actual implementation of DoThings() transparent to the concrete classes.
I have attempted covariance in the interface, however have been unable to avoid inheriting A which forces down the first code path.
The code above is a simplification of the actual implementation. There are about 10 classes deriving solely from A and 4 deriving from A and B.
I simply created an abstract hierarchy where abstract A is the base and there are 2 abstract classes inheriting from it.
I am having a C# abstract class which have some methods to be implemented by its children.
Though it is so, the initialization values for those children consist of two parts: one which is the same as the parent, and another one which is unique to the children.
public abstract class parentClass {
public abstract bool IsInputValid(string input); //children must implement this
public parentClass () {
//Some shared initialization
}
}
If the class is not abstract we could do something like this to implement that
public class parentClass {
public parentClass (string input) {
//Some shared initialization
}
}
public class childClass : parentClass {
public childClass (string input) : base (input) {
//Some unique initialization
}
}
But that cannot be done using abstract class and some more, the method not need not to be implemented (since it is not abstract).
So I am in a dilemma here. On one hand, I want to have some base initialization called and on the other, I also want to have some methods enforced.
So my question is, how do we normally implement such case? On one hand it is enforcing some base initialization, and on another some methods.
Note: I am new to abstract class so I would be glad to receive any inputs regarding it.
Where do I declare wrongly (if any)? If we cannot do so, is there a way to get around to produce the same result (that is, to enforce the child class to use certain signature for constructor)?
There should be no need to enforce this. You say that the base class has some common initialization and the child classes have their own specialized initialization as well.
This is enforced already, if you have this:
public abstract class Base
{
protected Base(int value) { ... }
}
Then you have a couple of guarantees:
Nobody can construct an object of the type Base since it is abstract
Nobody can construct an object that inherits from Base without indirectly calling the only existing constructor of Base, that takes an int value parameter.
The last part there is important.
A child class can deal with this type of base constructor in at least three ways:
It can provide a constructor that looks identical save the name of it, just passing the value down to the base constructor:
public class Child : Base
{
public Child(int value) : base(value) { ... }
}
It can provide a constructor that has this parameter but has additional parameters to the child class constructor as well:
public class Child : Base
{
public Child(int value, string other) : base(value) { ... }
}
It can provide a constructor that doesn't have the parameter to the base class, but manages to compute this parameter:
public class Child : Base
{
public Child(string other) : base(other.Length) { ... }
}
The last part also handles the case where the child constructor has no parameters at all:
public class Child : Base
{
public Child() : base(new Random().Next(100)) { ... }
}
Regardless of which approach you use, it is impossible to call the base class constructor without passing a value for that parameter, hence you have enforce the following:
Child classes has to be aware of the base class constructor and its parameter
But you cannot, and should not, try to enforce the presence of a particular constructor with a specific signature.
Now, having said that, what if you want to create some sort of common way to construct two distinct child classes, that has such different constructors, in such a way that code that uses them doesn't need to know the specifics of either constructor?
Enter the factory pattern (Wikipedia):
In class-based programming, the factory method pattern is a creational pattern that uses factory methods to deal with the problem of creating objects without having to specify the exact class of the object that will be created. This is done by creating objects by calling a factory method—either specified in an interface and implemented by child classes, or implemented in a base class and optionally overridden by derived classes—rather than by calling a constructor.
(quoted text copied from entry paragraph in the Wikipedia-article)
Here's a way to abstract away the presence and knowledge of such different constructors and child classes:
void Main()
{
Test(new Child1Factory());
Test(new Child2Factory());
}
public void Test(IBaseFactory baseFactory)
{
Console.WriteLine("In Test(...");
var b = baseFactory.Create();
}
public class Base
{
public Base(int value)
{
Console.WriteLine($"Base.ctor({value})");
}
}
public interface IBaseFactory
{
Base Create();
}
public class Child1 : Base
{
public Child1(int value) : base(value)
{
Console.WriteLine($"Child1.ctor({value})");
}
}
public class Child1Factory : IBaseFactory
{
public Base Create() => new Child1(42);
}
public class Child2 : Base
{
public Child2(string name) : base(name.Length)
{
Console.WriteLine($"Child2.ctor({name})");
}
}
public class Child2Factory : IBaseFactory
{
public Base Create() => new Child2("Meaning of life");
}
Pay special attention to the Test(...) method, as this has no knowledge of which Base child it will get, nor how to construct such an object. If you later on add new child types from Base, you will have to provide new factories as well but existing code that uses these factories should not need to be changed.
If you want a simpler factory pattern all you have to do is replace the interface and factory classes with a delegate:
void Main()
{
Test(() => new Child1(42));
Test(() => new Child2("Meaning of life"));
}
public void Test(Func<Base> baseFactory)
{
Console.WriteLine("In Test(...");
var b = baseFactory();
}
Final note here. Since the factory pattern means you will have to create a different type that does the actual construction of the object you can enforce the signature of that other type, either by
Adding parameters to the Create method on the factory interface
Specifying a delegate that has parameters to the factory delegate
This means you can enforce the signature of "the creation process". Still, you cannot enforce the presence or signature of a particular constructor, but the constructor is just a means to an end, create an object, and with the factory pattern you can actually formalize this pattern in your code and thus you should get what you want.
You cannot enforce the signature or even existence of constructors of your derived classes. (or any class for that matter)
I'm afraid that's the end of the story. You aren't doing anything wrong, it's just not possible.
Since you can't override constructors in c#, you cannot enforce the existence of a certain constructor in the derived class .
This means:
a constructor cannot be abstract, virtual etc
constructors aren't polymorphically
You cannot have an abstract constructor, but neither is there any need to.
All you need to do is remove the "abstract" keyword from your parentClass and you should be good to go.
I am trying to clean up an existing code base, and am having trouble with using a generic reference name to the different derived classes of an abstract class.
For instance:
public abstract class Base<T> : Utilities.CommonRequiredObject
{
protected List<T> RawContents = new List<T>();
.
.
public abstract void LoadContents(List<T> Contents); // Each Class needs to load and process differently
protected List<T> Contents;
public virtual void DoSomething() // Default here for common use. Defined in Each class for its specifics (if needed)
{
...
}
public abstract List<T> FunctionToGetContents();
}
public class FOO : Base<string>
{
public override void DoSomething() ...
public override List<string> FunctionToGetContents() ...
}
public class BAR : Base<byte>
{
public override void DoSomething() ...
public override List<byte> FunctionToGetContents() ...
}
Main Logic to try to use common variable. I want to create a new class to use, but want to use it then in a runtime polymorphic way. As the classes have the common functionality, and have overrides where needed, I want to be able to create an instance, and then use it:
IE: Base<T> ObjectToUse;
This way, I can simply refer to the ObjectToUse in the following code and call common methods. As I inherited some common routines from another base class, I am not sure if I can use an interface or not.
if(variable)
{
FOO ObjectToUse = new FOO();
}
else
{
BAR ObjectToUse = new BAR();
}
ObjectToUse.LoadContents(ObjectToUse.FunctionToGetContents());
ObjectToUse.DoSomething();
...
Edit:
Based on the comments I received quickly (thanks again everyone) would it be better than to remove the Generic (Base<T>) and have the classes all of type Base(), then I could define the ObjectToUse simply as Base ObjectToUse; I believe.
This cannot be done.
By utilizing a reference that requires a generic type parameter, you must give it one. You could utilize dynamic here so that the type is run-time evaluated, but thats the best you will get.
Even utilizing something like a template method pattern, you would need to specify the generic type argument. If you just want the DoSomething method for this, it would need to be promoted to a higher base class (or an interface) so you could hold a reference to that type, and call that (non-generic) function.
To your comment, the solution I would take is this; refactor the common code into a template method pattern within the base class. Then have the "triggering" function be a non-generic inherited member from a non-generic base class (or interface). Now, you can hold a reference to that type, and invoke the template method to cause the other calls to occur.
public void DoAwesomeStuff() //inherited from non-generic parent or interface
{
LoadContents(FunctionToGetContents());
DoSomething();
}
Then:
IDoesAwesomeStuff ObjectToUse = new FOO();
ObjectToUse.DoAwesomeStuff();
I'm writing an SDK which has an OOP structure for implementing data types;
first an interface
then an abstract implementation
finally an abstract generic implementation
People can choose to implement either the interface, or derive from either of the classes.
public interface IGoo
{
IGoo Duplicate();
...
}
public abstract class Goo : IGoo
{
IGoo IGoo.Duplicate() {
return Duplicate();
}
abstract public Goo Duplicate();
...
}
public abstract class Goo<T> : Goo
{
abstract public Goo<T> Duplicate(); ??????
...
}
I'd like to re-implement the Duplicate method so that it always returns the most specific type possible. I.e. when you call Duplicate on an IGoo instance, you get another IGoo. If you call it on Goo, you get Goo, if you call it on -say- Goo<int>, you get Goo<int>. And all Duplicate() methods always call the most specific implementation.
Is this possible? Is it only possible when you can implement an interface explicitly? In which case, should I not make Goo<int> derive from Goo, but have it implement IGoo instead and type all the low-level functionality twice?
What about the following?
public interface IObj
{
IObj Duplicate();
}
public abstract class Obj : IObj
{
public Obj()
{
}
public virtual IObj Duplicate()
{
return this;
}
}
public abstract class ObjT<T> : Obj
{
public ObjT()
{
}
public override IObj Duplicate()
{
return this;
}
}
public class ObjImpl : Obj
{
}
public class ObjTImpl : ObjT<int>
{
}
I understand that you want it to return the most specific type possible in any inheriting class but it actually is. It's boxing the inheriting type into the interface (or a raw object if you where to return objects instead of interface types. If you run the following test in a console app you will see the proper type is represented:
namespace TestConsole
{
class Program
{
static void Main(string[] args)
{
ObjImpl a = new ObjImpl();
ObjTImpl b = new ObjTImpl();
Console.WriteLine(a.Duplicate().GetType());
Console.WriteLine(b.Duplicate().GetType());
Console.ReadLine();
}
}
}
// outputs:
// ObjImpl
// ObjTImpl
The idea of redefining abstracts of abstracts goes against the purpose of abstract polymorphism. If the derived types do not intend to implement the inherited abstract member, they should not be inheriting it.
Although the example I gave above would require casting to access any child class-specific members, it would be the proper way to do it in this approach. The runtime needs to know what types it should expect to deal with.
There is always dynamics you could play around with but to be honest I haven't played around with dynamics with generics and inheritance as I suspect I would make my compiler cry, and when it cries, I cry, a little bit deep down inside... lol
It is only possible when you implement the interface explicitly. That's because the return type of a method is not part of its signature - which the compiler checks when overloading. Therefore, otherwise identical methods which only differ in their return type are syntactically not possible.
public abstract class A
{
// constructors omitted
public abstract A Create(SomeData data);
}
public class B : A
{
// constructors omitted
public override A Create(SomeData data)
{
return new B(data);
}
}
What I want is to be able to make the Create method static, so that I can get an instance of B without having to create a useless instance with an empty constructor. (If you're wondering why, A is actually a generic type of the form A<TFoo, TBar>, where TBar corresponds to the derived types. As we all know, you can't instantiate a generic type using a constructor that takes any arguments.)
I am already aware that static methods are decoupled from the object hierarchy, only relying on the name of the type. That means I can't have Create as an abstract method that I force all descendants to implement. Is there another way I can implement this pattern?
Something like this might work, depends on your requirements
public abstract class A
{
public string Data { get; set; }
public static T Create<T>(string data) where T : A, new()
{
return new T() { Data = data };
}
}
public class B : A { }
then can do
A foo = A.Create<B>("foo");
There is simply no way to do this. Inheritance is based off of instance methods in C# and has no equivalent feature for static methods. Another way to implement this pattern though is to require a lambda in lieu of a static method.
For example (you mentioned the actual type was A<TFoo, TBar>)
void UseIt<TFoo, TBar>(A<TFoo, TBar> p, Func<SomeData, TBar> func) {
TBar b = func();
...
}
The consumer doesn't care if Create is static, instance or even called create. Generally all they care about is having a function which takes a SomeData and returns a TBar. Delegates fit this pattern exactly.