Self-referenced generic parameter - c#

For example I have the following classes:
1.
class MyClass1
{
public MyClass1 Method()
{
...
return new MyClass1();
}
}
class MyClass2
{
public MyClass2 Method()
{
...
return new MyClass2();
}
}
The methods have the same bodies that's why I want to extract the code and re-use.
2.
abstract class MyClass
{
protected void Method()
{
...
}
}
class MyClass1 : MyClass
{
public MyClass1 Method()
{
base.Method();
return new MyClass1();
}
}
class MyClass2 : MyClass
{
public MyClass2 Method()
{
base.Method();
return new MyClass2();
}
}
However since there are a lot of such methods it will be better to move the methods into the base class MyClass at all:
3.
abstract class MyClass<T>: where T : MyClass<T>
{
protected abstract T Create();
public T Method()
{
...
return Create();
}
}
class MyClass1 : MyClass<MyClass1>
{
protected override MyClass1 Create() => new MyClass1();
}
class MyClass2 : MyClass<MyClass2>
{
protected override MyClass2 Create() => new MyClass2();
}
It works fine but the contract looks too weird. Of course, I can extract something like IMyInterface and return it instead of the class. However I have to preserve the original contract because it contains specific methods as well.
Upd: So, the weird thing is in bold - class MyClass1: MyClass<MyClass1>

This is the usual so-called self-type problem (you have Method() should return the same type as the object on which it was called). Your solution #3 looks a lot like F-bounded quantification. However, this is C#, not Java, so we can do a bit better using an extension class.
You can make sure those methods only get called on subclasses of MyClass by adding a where T : MyClass bound on T.
// Put all your shared methods in generic classes in here.
public static class MyMethods
{
public static T Method<T>(this T x) where T : MyClass
{
...
}
}
Your classes don't change much, except they won't need to mention Method (or the other shared methods) at all.
public abstract class MyClass
{
...
}
public class MyClass1 : MyClass
{
...
}
public class MyClass2 : MyClass
{
...
}

Yes it looks a little bit weird to have a method which only create.
Because you have a 2 classes MyClass1 and MyClass2 which have their specific different methods and only base method is common (which you put in base class) I think you can use Abstract factory pattern.
public class ClassFactory: IClassFactory
{
public MyClass Create()
{
if (some condition)
return new MyClass1;
return new MyClass2;
}
}
class MyClass
{
protected string CommonLogic()
{
//common logic
return string;
}
}
class MyClass1 : MyClass
{
public object SpecificMethod()
{
CommonLogic();
.....
}
}
class MyClass2 : MyClass
{
public object SpecificMethod2()
{
CommonLogic();
.....
}
}
In this case you won't have duplicated code and you will have some class which one will have responsibility about creating you classes and will know when and which class return. + You will easy use it IoC here.
I hope my answer will help you.

There are some rare situations where a self-referencing type constraint may be needed, but I am not convinced that this is one of them.
It seems that you want to use the factory (Create) pattern and also have those factories return different concrete types. But at the same time you are saying that these concrete types all have something in common, specified by the base class.
The conventional approach would be to define the common features in an interface (IMyInterface as you suggested) and return that from the Create method. This would capture the polymorphic aspect of the concrete classes. Then the question is how to capture the other methods that are implemented in the concrete types. For this one can simply define additional interfaces that capture the various clusters of functionality implemented by more than one of the concrete classes.
To the extent that there are any dribs and drabs of functionality left over after you've done that, I would say handle them by casting would be the easiest -- at that point the functionality would be unique to just one of the concrete classes. If you want to fly with your eyes closed you could use the 'dynamic' type instead of casting.
Also, normally the Create method is not defined in the object instances, in other words normally objects are not their own factories. Typically they are either static or in a separate factory classes. In the current situation a bit of reflection helps deal with the fact that you have multiple derived types. There are various ways to do this besides what I show below.
So … perhaps something like this:
public interface ICommonFunctionality
{
void SomethingThatEveryoneCanDo();
// ... other common functionality
}
public interface IAdditionalFunctionality1
{
void SomethingThatAFewCanDo();
// ... other special functionality
}
public interface IAdditionalFunctionality2
{
void SomethingThatOthersCanDo();
// ... other special functionality
}
public class MyClass : ICommonFunctionality
{
static public ICommonFunctionality Create(Type derivedType)
{
if (!typeof(ICommonFunctionality).IsAssignableFrom(derivedType)) { throw new ArgumentException(); }
return derivedType.CreateInstance() as ICommonFunctionality;
}
virtual public void SomethingThatEveryoneCanDo() { /* ... */ }
}
public class MyClass1 : MyClass, IAdditionalFunctionality1
{
public void SomethingThatAFewCanDo() { /* ... */ }
}
public class MyClass2 : MyClass, IAdditionalFunctionality1, IAdditionalFunctionality2
{
public void SomethingThatAFewCanDo() { /* ... */ }
public void SomethingThatOthersCanDo() { /* ... */ }
}
public class MyClass3 : MyClass, IAdditionalFunctionality2
{
public void SomethingThatOthersCanDo() { /* ... */ }
}
public static class TypeHelpers
{
public static object CreateInstance(this Type type, bool required = true)
{
System.Reflection.ConstructorInfo ctor = type.GetConstructor(Type.EmptyTypes);
if (required && ctor == null) { throw new InvalidOperationException("Missing required constructor."); }
return ctor?.Invoke(null);
}
}
P.S. I have made the base class method virtual, this is pretty much optional depending on your situation.

Related

Accessing internal methods through a public interface [duplicate]

This question already has answers here:
How to Mock the Internal Method of a class?
(6 answers)
Closed 4 years ago.
The Situation
Suppose I have a class with an internal method:
class MyClass : IMyClass
{
public void PublicMethod() { ... }
internal void InternalMethod() { ... }
}
that implements an interface:
interface IMyClass
{
void PublicMethod() { ... }
}
And a container class that holds an instance of MyClass and other concrete classes:
class ContainerClass
{
public MyClass myClass;
...
}
ContainerClass is used by various assemblies. When used within the same assembly as MyClass the calling method can invoke containerClass.myClass.InternalMethod()
The Problem
In an effort to make things more easily mockable for testing, I am now trying to replace the ContainerClass's properties with interfaces rather than concrete classes, e.g.:
class ContainerClass
{
public IMyClass myClass;
...
}
But, if I do that, InternalMethod can no longer be invoked using containerClass.myClass.InternalMethod() because the method doesn't exist on the interface... nor can it, because it is internal. However, I cannot make the interface internal because ContainerClass is used by other assemblies as well.
Let's assume that I cannot change the internal access to that method. Is there another way?
EDIT: This is different from How to Mock the Internal Method of a class? because I am not trying to mock the internal method, I am trying to keep it exposed when replacing a concrete class (MyClass) with an interface (IMyClass).
An option is to create two interfaces, one public and one internal:
public interface IMyClassPublic
{
void PublicMethod();
}
internal interface IMyClassInternal
{
void InternalMethod();
}
Implement both of them in MyClass (you need to implement IMyClassInternal explicitly since it's internal):
public class MyClass : IMyClassPublic, IMyClassInternal
{
public void PublicMethod() { }
void IMyClassInternal.InternalMethod() { }
}
And change ContainerClass so that it exposes both interfaces separately (and probably make myClass private):
public class ContainerClass
{
private MyClass myClass;
public IMyClassPublic myClassPublic
{
get
{
return myClass;
}
}
internal IMyClassInternal myClassInternal
{
get
{
return myClass;
}
}
}
Now you can mock both of them, use the internal method as containerClass.myClassInternal.InternalMethod() and the public method as containerClass.myClassPublic.PublicMethod().

Defining interface dependency that implements generics

This will be generics 101 for many but below is sample code so I can understand better.
public interface IRecordedItemsProcessor<T>
{
ObservableCollection<RecordedItem> Load(string name);
void Save();
RecordedItem Parse(T itemToParse);
}
public class FileLoadingProcessor : IRecordedItemsProcessor<string>
{
public ObservableCollection<RecordedItem> Load(string name)
{
}
public void Save()
{
}
public RecordedItem Parse(string itemToParse)
{
}
}
public class MyClass
{
public MyClass(IRecordedItemsProcessor<T> processor)
{
}
}
The issue is that MyClass needs a dependency on IRecordedItemsProcessor<T> but will not compile as it does not know what T is. How can this be resolved? Making MyClass implement a seems odd as all it needs to do is call Load/Save
Thanks
First solution is the most simple one: lift generic declaration to class level, like
public class MyClass<T>
{
public MyClass(IRecordedItemsProcessor<T> processor)
{
}
}
Then you could instantiate MyClass as following:
var myClass = new MyClass<string>(new FileLoadingProcessor());
Console.WriteLine (myClass);
Second solution is a removing generic input from constructor and inferring types. Then you don't need to specify generic exactly from call. Class declaration will look like:
public class MyClass
{
public void Process<T>(IRecordedItemsProcessor<T> processor)
{
}
}
And then you can call simply
var my = new MyClass();
my.Process(new FileLoadingProcessor());
The Idea is that you always need to specify class-level generics explicitly, but method level generics can be inferred by the compiler.
Third solutions is to encapsulate creation mechanisms inside MyClassFactory. This is quite flexible, but it might seem a little bit complicated, because descendants of IRecordedItemsProcessor<T> don't define generic at class level, so we should go to implemented interfaces and grab there generic types. And only then we can construct Generic MyClass. Listing is given below:
public class MyClassFactory
{
public MyClass<T> MakeMyClassFor<T>(IRecordedItemsProcessor<T> processor)
{
var processorGenericType = processor.GetType()
.GetInterfaces()
.Single(intr=>intr.Name == "IRecordedItemsProcessor`1")
.GetGenericArguments()[0];
var myClassType = typeof(MyClass<>).MakeGenericType(processorGenericType);
return Activator.CreateInstance(myClassType, processor) as MyClass<T>;
}
}
Now you can create MyClass very simply
var myClassFactory = new MyClassFactory();
var res = myClassFactory.MakeMyClassFor(new FileLoadingProcessor());
Console.WriteLine (res);
All of these three approaches have their pros and cons. Consider taking into account the context, in which you are going to use them.
You could do the following:
Create a new interface IRecordedItemsProcessor (non-generic)
Move Load and Save to this IRecordedItemsProcessor
Make IRecordedItemsProcessor<T> inherit from this IRecordedItemsProcessor
Make MyClass expect IRecordedItemsProcessor in its constructor
This makes it clear that MyClass doesn't care what type the processor might be able to parse, or even that it can parse things at all - it only knows that it can save and load.
You could inherit from a non-generic marker interface, this removes the need to know about T in your class:
public interface IRecordedItemsProcessor
{
}
public interface IRecordedItemsProcessor<T> : IRecordedItemsProcessor
{
ObservableCollection<RecordedItem> Load(string name);
void Save();
RecordedItem Parse(T itemToParse);
}
And then you can use any IRecordedItemsProcessor like:
public class MyClass
{
public MyClass(IRecordedItemsProcessor processor)
{
}
}
The generic type, as written, is being declared on the MyClass constructor which means the generic type must be defined at the MyClass level:
public class MyClass<T>
{
public MyClass(IRecordedItemsProcessor<T> processor)
{
}
}
However, if the generic type was declared at a method level, it would only have to be defined at the method level:
public class MyClass
{
public void MyMethod<T>( IRecordedItemsProcessor<T> processor )
{
}
}
EDIT
Based on your comment:
I want a class that can call the Load/Save methods but not be worried
that T is.
Then you'll need 2 interfaces: 1 for the load/save and then one with the parsing. In this case, you could use inheritance:
public interface IRecordedItems
{
ObservableCollection<RecordedItem> Load( string name );
void Save();
}
public interface IRecordedItemsProcessor<T> : IRecordedItems
{
RecordedItem Parse( T itemToParse );
}
public class MyClass : IRecordedItems
{
#region Implementation of IRecordedItems
public ObservableCollection<RecordedItem> Load( string name )
{
throw new NotImplementedException();
}
public void Save()
{
throw new NotImplementedException();
}
#endregion
}
EDIT 2
Based on your gist example, the type dependency could be moved off of the interface and directly into the interface method:
public class RecordedItem {}
public interface IRecordedItemsProcessor
{
ObservableCollection<RecordedItem> Load( string name );
void Save();
RecordedItem Parse<T>( T itemToParse );
}
public class MyClass
{
private readonly IRecordedItemsProcessor _processor;
public MyClass( IRecordedItemsProcessor processor )
{
_processor = processor;
processor.Parse<string>( "foo" );
processor.Parse<int>( 10 );
processor.Parse<RecordedItem>( new RecordedItem() );
}
}

Problem with Abstract class, Interface, Container and methods

I've the following scenario
I've an Interface
public interface ImyInterface
{
void myInterfaceMethod(string param);
}
I've an Abstract Class
public abstract class myAbstractClass
{
public myAbstractClass()
{
//something valid for each inherited class
}
public void myAbstractMethod<T>(T param)
{
//something with T param
}
}
I've a class that inherits from myAbstractClass and implements ImyInterface
public class myClass : myAbstractClass, ImyInterface
{
public myClass():base()
{}
public void ThisMethodWillNeverCall()
{
// nothing to do
}
}
And, finally, I've a class where I'll create a ImyInterface object. At this point I would call myAbstractMethod, but...
public class myFinalClass
{
public void myFinalMethod()
{
ImyInterface myObj = _myContainer<ImyInterface>();
myObj.???
}
}
Obviously there isn't this method because it isn't declared into the interface.
My solution is the following
public interface ImyInterface
{
void myInterfaceMethod(string param);
void myFakeMethod<T>(T param);
}
public class myClass : myAbstractClass, ImyInterface
{
public myClass():base()
{}
public void ThisMethodWillNeverCall()
{
// nothing to do
}
//--- a fake method
public void myFakeMethod<T>(T param)
{
base.myAbstractMethod<T>(param);
}
}
Is there any other solution better than mine?
Thank you!
First of all, your naming convention is a mess. Read up on the guidelines that Microsoft have made.
It's also hard to tell what you are trying to achieve based on your example.
Back to your question:
You should only access an interface to work with that interface. Don't try to make any magic stuff with classes/interfaces to get them working together. That usually means that the class shouldn't try to implement the interface.
It's better that you create a new interface which have the features that you want and let your class implement both.

Overriding a nested class functions or use delegates?**

I have a base class which has a nested type, inside. There's a function in the outer (base) type which would be overridden by it's children later. In fact this function belongs to the inner type from the OO prespective but still I need it, to be overridden by subtypes of the base class.
Should I use this function as a callback from the inner type or just move it inside the inner type and let's the subtypes to override it from there?
EDIT: Sample code added
class A
{
protected void func() { /* do something */ }
class B { /**/ }
}
// OR
class A
{
class B
{
protected void func() { /* do something */ }
}
}
// Then
class C : A
{
override func() { /**/ }
}
My suggestion is to crate a delegate for the inner type function which is initiated by the constructor of the base class:
internal class BaseClass
{
public BaseClass(Action myAction)
{
this.innerType = new InnerType(myAction);
}
public BaseClass()
{
// When no function delegate is supplied, InnerType should default to
// using its own implementation of the specific function
this.innerType = new InnerType();
}
}
As you see, deriving types can call the base constructor with :base (overridenAction) where they can provide their own implementation of the function right to the innermost type. Of course, you are not obligated to use Action but any delegate you want.
IMO what you are describing looks like The Strategy design pattern. Consider using this pattern. Your code would be much more maintainable as it contains well recognizable pattern. You also can take a look at state design pattern, usually you have to choose between these two, they are closely connected.
In this scenario:
class A
{
class B
{
protected void func() { // do something }
}
}
You cannot derive from class A and override func() in class B.
From your description it seems that A-derived classes should be able to override some function (or functionality) in the inner class B which indicates that you maybe should rethink your design. Either extract B and don't make it an inner class or make the functionality you want to override an explicit dependency via an interface like this:
class A
{
private B _MyB;
public A(ISomeBehaviour behaviour)
{
_MyB = new B(behaviour);
}
}
In anyway if you want to stick with your design then I would not recommend the delegate approach and rather choose the override because with the delegates it makes it harder to add decoration if that is all you need in your child classes.
This is how the outer class can serve as a strategy to the inner service class.
Note that using pattern names such as TemplateMethod and Strategy as real class names is not recommended, use whatever is meaningful in the domain. Same applies to Outer and Inner.
public class Consumer
{
public void Foo()
{
IOuterFoo fooService = new Derived();
fooService.OuterFoo();
}
}
// ...
public interface IOuterFoo
{
void OuterFoo();
}
abstract class Base : Base.IStrategy, IOuterFoo
{
public void OuterFoo() { _service.Foo(); }
private readonly InnerService _service;
protected Base() { _service = new InnerService(this); }
private interface IStrategy { void Foo(); }
private class InnerService
{
private readonly IStrategy _strategy;
public InnerService(IStrategy strategy) { _strategy = strategy; }
public void Foo() { _strategy.Foo(); }
}
void IStrategy.Foo() { TemplateMethodFoo(); }
protected abstract void TemplateMethodFoo();
}
class Derived : Base
{
protected override void TemplateMethodFoo()
{
throw new NotImplementedException();
}
}

How can I factor out the code duplication here?

So, I'd like to hear what you all think about this.
I have a project where three different inheritance paths need to all implement another base class. This would be multiple inheritance and isn't allowed in C#. I am curious how I can implement this without code duplication.
EDIT: I don't own the three classes. The three classes are from 3rd party code. So I cannot make them all extend my base class.
Right now I am using three different classes, each one extending a different base class. Then I have the same code in each of the three abstract classes.
I could use a single interface, but I would still need to duplicate the code.
I could make some kind of static class that implements the code and then reference that in each of the 3 abstract classes. It would eliminate the duplication, but, I am not sure how I feel about this. I could implement Extensions methods on the interface, but then the interface itself would be empty and the extension methods (containing the duplicate code) would be in a totally different file, which seems not quite right. Plus I can't implement properties in extension methods...
How can I factor out the code duplication here?
EDIT, inheritance tree:
class Class1 : 3rdPartyBaseClass1 { }
class Class2 : 3rdPartyBaseClass2 { }
class Class3 : 3rdPartyBaseClass3 { }
I have code I want to be in each of the above Classes, but I cannot add it to the 3rdPartyClasses.
Create an interface that Class1, Class2, and Class3 can implement. Then put your code in extension methods so it will apply to all.
interface IMyInterface {
void Foo(); //these are the methods that these
//classes actually have in common
void Bar();
}
public class Class1 : 3rdPartyBaseClass1, IMyInterface {
// whatever
}
public static class IMyInterfaceExtensions {
public static void CommonMethod(this IMyInterface obj) {
obj.Foo();
obj.Bar();
}
}
public static class Program {
public static void Main() {
var instance = new Class1();
instance.CommonMethod();
}
}
OK, you can do something similar to my previous suggestion, and also similar to recursive's suggestion. For the functionality you require in all three of your derived classes, you can create a single Interface along with a single class (call it "Implementer" for kicks) that implements that Interface (and that has the actual code you want executed with each call).
In each of your derived classes, then, you implement the Interface and create a private instance of Implementer. In each of the interface methods, you just pass the call along to the private instance of Implementer. Because Implementer and your derived classes all implement your Interface, any changes you make to the Interface will require you to modify Implementer and the derived classes accordingly.
And all your code is in one place, except for all the lines passings the calls on to the private instance of Implementer (obviously multiple inheritance would be better than this, but you go to war with the army you have, not the army you wish you had).
Update: what about just adding a public instance of your class to each of the derived classes?
public class DerivedClass1 : ThirdPartyClass1
{
public MyClass myClass = new MyClass();
}
Or if you care who Demeter is and you get paid by LOC:
public class DerivedClass1 : ThirdPartyClass1
{
private MyClass _myClass = new MyClass();
public MyClass myClass
{
get
{
return _myClass;
}
}
}
Then you'd just call the MyClass methods like this:
DerivedClass1 dc1 = new DerivedClass1();
dc1.myClass.DoSomething();
This way, we could all go to sleep.
Similar to MusiGenesis's suggestion, if you need the functionality of the 3rd party classes but do not have to descend from them, you could use composition as follows:
class ThirdPartyBaseClass1
{
public void DoOne() {}
}
class ThirdPartyBaseClass2
{
public void DoTwo() { }
}
class ThirdPartyBaseClass3
{
public void DoThree() { }
}
abstract class Base
{
public void DoAll() { }
}
class Class1 : Base
{
public void DoOne() { _doer.DoOne(); }
private readonly ThirdPartyBaseClass1 _doer = new ThirdPartyBaseClass1();
}
class Class2 : Base
{
public void DoTwo() { _doer.DoTwo(); }
private readonly ThirdPartyBaseClass2 _doer = new ThirdPartyBaseClass2();
}
class Class3 : Base
{
public void DoThree() { _doer.DoThree(); }
private readonly ThirdPartyBaseClass3 _doer = new ThirdPartyBaseClass3();
}
This also gives you the freedom to define whatever interfaces you want and implement them on your classes.
Sounds like you need to insert the new abstract class into the inheritance tree at whatever point those three paths come together, but there really isn't enough information to tell. If you could post some of your inheritance tree, that would help a lot.
I think you may want to use composition instead of inheritance. Exactly how to do this depends on what the third party classes look like, and what your own code looks like. Some more specific code relating to your problem would be helpful, but for example, suppose you want to have three different third party GUI widgets that all need to be customized with your own initializer code.
Case 1: Suppose your third party widgets look like:
public interface IThirdPartyWidget {
public void doWidgetStuff();
}
public class ThirdPartyWidget1: ThirdyPartyWidget implements IThirdPartyWidget {
...
}
public class ThirdPartyWidget2: ThirdPartyWidget implements IThirdPartyWidget {
...
}
You can do:
public class MyWidget implements IThirdPartyWidget {
private IThirdPartyWidget delegateWidget;
public MyWidget(IThirdPartyWidget delegateWidget) {
this.delegateWidget = delegateWidget;
}
public void doWidgetStuff() {
delegateWidget.doWidgetStuff();
}
}
Case 2: Suppose you absolutely need to extend those widgets, and you have to refactor your own code:
public class MyWidget1: ThirdPartyWidget1 {
public void myMethod() {
runMyCode();
}
private void runMyCode() {
//something complicated happens
}
}
public class MyWidget2: ThirdPartyWidget2 {
public void myMethod() {
runMyCode();
}
private void runMyCode() {
//something complicated happens
}
}
This can become:
public class MyCodeRunner {
public void runMyCode() {
//...
}
}
public class MyWidget1: ThirdPartyWidget1 {
private MyCodeRunner myCode = new MyCodeRunner();
public void myMethod() {
myCode .runMyCode();
}
}
public class MyWidget2: ThirdPartyWidget2 {
private MyCodeRunner myCode = new MyCodeRunner();
public void myMethod() {
myCode .runMyCode();
}
}
Hope this makes sense!

Categories