I need to create two partial interfaces. One with a constraint and the other without, like:
public partial interface IMyCuteInterface<T> where T : IEnumerable
{
void DoSomethingOnlyPossibleIfGenericIsIEnumerable();
}
public partial interface IMyCuteInterface<T>
{
void DoSomeStuff();
void DoSomeStuff2();
}
This is the implementation:
public class CuteInterfaceImplementation<T> : IMyCuteInterface<T>
{
private readonly T _element;
public CuteInterfaceImplementation(T element)
{
_element = element;
}
public void DoSomethingOnlyPossibleIfGenericIsIEnumerable(){}
public void DoSomeStuff(){}
public void DoSomeStuff2() { }
}
This is a static method to get this more dynamically:
public class CuteInterfaceImplementationBase
{
public static IMyCuteInterface<T> From<T>(T t)
{
return new CuteInterfaceImplementation<T>(t);
}
}
and this is the way I want to call it:
public static void Main(string[] args)
{
var mci = CuteInterfaceImplementationBase.From(args);
}
So, C# wants me to add the generic type constraint I added in the first interface to my CuteInterfaceImplementationBase.From<T> and my CuteInterfaceImplementation<T>-class.
What I want to achieve is: args could either be e.g. from type List<T> or from type int or something else. My target is, if args is from type IEnumerable<T> I want to add more functions (via the interface with the constraint) to CuteInterfaceImplementation-instance.
example:
if args is from type IEnumerable, this instance from CuteInterfaceImplementation has methods:
void DoSomethingOnlyPossibleIfGenericIsIEnumerable();
void DoSomeStuff();
void DoSomeStuff2();
if args is from type Foo or int (or any type that doesn't implement IEnumerable) I can use methods:
void DoSomeStuff();
void DoSomeStuff2();
means, DoSomethingOnlyPossibleIfGenericIsIEnumerable is not available.
But it seems, this is not possible, since I need to add the constraint to my implemented class. Any idea how to do this?
Not sure that this approach good idea, it violates the "I" in SOLID - interface
segregation
no client should be forced to depend on methods it does not use
You're using partial to split up two fundamentally different interfaces, you should have 2 different interface because they are different.
To answer your question:
If you're committed to a similar approach on the conditions of T, you could split the interfaces, move the "common logic" (which both interfaces use) to a base class and use the From<T> method to conditionally choose which implementation to create.
Something like this:
public partial interface IMyCuteInterface_WITHEnumerable<T> : IMyCuteInterface<T> where T : IEnumerable
{
void DoSomethingOnlyPossibleIfGenericIsIEnumerable();
}
public partial interface IMyCuteInterface<T>
{
void DoSomeStuff();
void DoSomeStuff2();
}
And then the implementations:
public class CuteInterfaceImplementation<T> : CuteInterfaceImplementation_COMMON<T>
{
public CuteInterfaceImplementation(T element) : base(element)
{
}
}
public class CuteInterfaceImplementation_COMMON<T> : IMyCuteInterface<T>
{
private readonly T _element;
public CuteInterfaceImplementation_COMMON(T element)
{
_element = element;
}
public void DoSomeStuff() { }
public void DoSomeStuff2() { }
}
public class CuteInterfaceImplementation_WITHEnumerable<T> : CuteInterfaceImplementation_COMMON<T>, IMyCuteInterface_WITHEnumerable<T> where T : IEnumerable
{
private readonly T _element;
public CuteInterfaceImplementation_WITHEnumerable(T element) : base(element)
{
_element = element;
}
public void DoSomethingOnlyPossibleIfGenericIsIEnumerable() { }
}
Finally your "static helper", which decides on the class to instantiate:
Unfortunately it's not possible in C# to conditionally instantiate the different classes because one expects T to be IEnumerable while the other doesn't. You can get around that using dynamic
public class CuteInterfaceImplementation_HELPER
{
public static IMyCuteInterface<T> From<T>(T t)
{
if (t is IEnumerable)
{
dynamic dyn = t;
return FromEnumerable(dyn);
}
else
{
return new CuteInterfaceImplementation<T>(t);
}
}
public static IMyCuteInterface<T> FromEnumerable<T>(T t) where T: IEnumerable
{
return new CuteInterfaceImplementation_WITHEnumerable<T>(t);
}
}
Related
This is probably a classic covariance/contravariance question, it looks like it should work but I'm probably missing a trick.
I'm attempting to return a less derived type from a factory method, but I find that I cannot cast the more specialized concrete instance to a less derived base type.
public class AnimalSettings { ... }
public class CatSettings : AnimalSettings { ... }
public interface IAnimalService<TSettings> { ... }
public abstract AnimalService<TSettings> : IAnimalService<TSettings> where TSettings : AnimalSettings { ... }
public class CatService : AnimalService<CatSettings> { ... }
Then, in a factory method I have:
public static IAnimalService<AnimalSettings> GetAnimalService(AnimalType selector)
{
switch (selector)
{
case AnimalType.Cat:
return (IAnimalService<AnimalSettings>) new CatService();
break;
}
}
and the intention is to be able to do the following:
var service = MyServiceFactory.GetAnimalService(AnimalType.Cat);
service.DoAnimalBehavior();
This compiles fine, but at runtime my code is failing in the attempted cast return (IAnimalService<AnimalSettings>) new CatService();, with an InvalidCastException.
How should I be casting my more derived type to a less derived type so that callers can use that interfaced base type to invoke functionality?
Changing the cast to (IAnimalservice<CatSettings>) new CatService() does work, but it's intended that the caller receives a IAnimalservice<AnimalSettings> so that it can handle any sort of animal (In other words, the caller should not be using any of the more specialized types). Should I be specifying an in or out as part of the generic definition somewhere?
By giving a complete example it would be much easier to help. ;-)
So here is the working code. And as Sweeper already mentioned, you need to add the out parameter at the interface to make it work.
using System;
public class Program
{
public static void Main()
{
var catService = new CatService(new CatSettings());
var genericService = (IAnimalService<AnimalSettings>)catService;
genericService.DoAnimalBehavior();
}
}
public abstract class AnimalSettings
{
public abstract void DoAnimalBehavior();
}
public class CatSettings : AnimalSettings
{
public override void DoAnimalBehavior()
{
Console.WriteLine("Meeoh");
}
}
public interface IAnimalService<out TSettings>
{
void DoAnimalBehavior();
}
public abstract class AnimalService<TSettings> : IAnimalService<TSettings> where TSettings : AnimalSettings
{
private readonly TSettings _settings;
public AnimalService(TSettings settings)
{
_settings = settings;
}
public void DoAnimalBehavior()
{
_settings.DoAnimalBehavior();
}
}
public class CatService : AnimalService<CatSettings>
{
private readonly CatSettings _catSettings;
public CatService(CatSettings catSettings)
: base(catSettings)
{
_catSettings = catSettings;
}
}
I have got two abstract classes: Particle and ParticleHub<T> where T : Particle.
I want, when I inherit Particle, for its constructor to require a ParticleHub of its respective type to be passed as a parameter. I want its constructor to be like this:
ParticleHub</*type of the inheriting class*/> _particleHub;
public Particle(ParticleHub</*type of the inheriting class*/> particleHub, OtherParameters otherParameters)
{
_particleHub = particleHub;
//use other parameters
}
If I write ParticleHub<typeof(this)> I get overloaded with errors that make me think I broke the syntax for the rest of the file. If I do ParticleHub<this.GetType()> I get the same problem, but only with fewer errors. Though with that one, I can understand that I can't use a function in a parameter type like that.
So how do I go about this?
Simple example below of an interface and generic pattern
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello World!");
IChair chair = new Chesterfield<Arm>(new Arm());
chair.Sit();
Console.Write(chair.HasSat());
}
}
public interface IChair
{
void Sit();
bool HasSat();
}
public interface IPart
{
}
public class Chesterfield<TPart> : Chair<TPart> where TPart : IPart
{
public Chesterfield(TPart part) => _part = part;
private bool _hasSat;
private readonly TPart _part;
public override void Sit()
{
_hasSat = true;
}
public override bool HasSat() => _hasSat;
}
public abstract class Chair<TPart> : IChair where TPart : IPart
{
public abstract void Sit();
public abstract bool HasSat();
}
public class Arm : IPart
{
}
public class Back : IPart
{
}
public class Leg
{
}
You have no other choise i think but to pass the type as other generic. See the exaple how it is done in terms of fluent builders as I think it is very close what You want to have: Link.
Like:
FePatricle<T, U> where T: Particle, U: FeParticle<T, U>
Looks crazy but it should do the trick in the constructor:
public FeParticle(ParticleHub<U>...
EDIT:
Or more likely as far as I understand:
FePatricle<T>: Particle where T: FeParticle<T>
So FePartivle extends Particle and it carries with itself its own type T?
Passing the inherited class itself, as below.
public abstract class Particle
{
}
public abstract class ParticleHub<T> where T : Particle
{
}
public class k1 : Particle
{
ParticleHub<k1> _particleHub = null;
public k1(ParticleHub<k1> ph)
{
_particleHub = ph;
}
}
So I have a very big Generic class 1500+ rows and growing, with loads of methods. It has CrazyMethods and GoodMethods, I want to put the different kinds of methods in their own class but still be able to use my generic as if they were inside the generic class.
public class MyGeneric<T> : IMyGeneric<T> where T : IEntity
{
public MyGeneric(string stuff)
{
moreStuff(stuff);
}
// Region Good
public void MyGoodMethod1(T entity)
{
//does good stuff with the generic..
}
public T MyGoodMethod2()
{
//does other good stuff with the generic..
}
//Region Crazy
public void MyCrazyMethod1(T entity)
{
//does crazy stuff with the generic..
}
public T MyCrazyMethod2()
{
//does other crazy stuff with the generic..
}
}
Now in my other project where I use this generic it looks something like this
...
SomeObject _myObject = new MyGeneric<SomeObject>("ladida");
_myObject.MyGoodMethod1();
//..Other stuff
_myObject.MyCrazyMethod2();ยจ
...
How do I separate the methods from the MyGeneric class into separate classes (MyGenericGoodMethods.cs, MyGenericCrazyMethods.cs) but still be able to use them the way I showcased above ?
If I could use extension methods for generics that would be the perfect solution.
public static class MyGenericGoodMethods<T> where T : IEntity
{
public static T Method2(this MyGeneric<T> generic)
{
//does other good stuff with the generic..
}
}
but
Extension method can only be declared in non generic, non nested, static class
You can declare extension method in normal static class and use it with generic.
public static class MyGenericGoodMethodsExtensions
{
public static T Method2(this MyGeneric<T> generic)
{
//does other good stuff with the generic..
}
}
var myGeneric = new MyGeneric<string>();
myGeneric.Method2()
But you can always split your giant class in many separated generic classes and use them inside your main-generic class.
Split up your interfaces
public interface IMyGeneric<T>
{
void MyGeneric(string stuff);
}
public interface IMyGoodGeneric<T>
{
void MyGoodMethod1(T entity);
void MyGoodMethod2(T entity);
}
public interface IMyCrazyGeneric<T>
{
void MyCrazyMethod1(T entity);
void MyCrazyMethod2(T entity);
}
Introduce separated implementation
public class MyGeneric<T> : IMyGeneric<T> where T : IEntity
{
public void MyGeneric(string stuff)
{
// implementation
}
}
public class MyGoodGeneric<T> : IMyGoodGeneric<T> where T : IEntity
{
public void MyGoodMethod1(T entity) {}
public void MyGoodMethod2(T entity) {}
}
public class MyCrazyGeneric<T> : IMyCrazyGeneric<T> where T : IEntity
{
public void MyCrazyMethod1(T entity) {}
public void MyCrazyMethod2(T entity) {}
}
Then you can create your "giant" composition class which will implement all interfaces and use already existed implementations
public class MyGiantGeneric<T> : IMyGeneric<T>,
IMyGoodGeneric<T>,
IMyCrazyGeneric<T> where T : IEntity
{
private readonly IMyGeneric<T> _myGeneric;
private readonly IMyGoodGeneric<T> _myGoodGeneric;
private readonly IMyCrazyGeneric<T> _myCrazyGeneric;
public MyGiantGeneric(IMyGeneric<T> myGeneric,
IMyGoodGeneric<T> myGoodGeneric,
IMyGCrazyGeneric<T> myCrazyGeneric)
{
_myGeneric = myGeneric;
_myGoodGeneric = myGoodGeneric;
_myCrazyGeneric = myCrazyGeneric;
}
public void MyGeneric(string stuff)
{
_myGeneric.MyGeneric(stuff);
}
public void MyGoodMethod1(T entity)
{
_myGoodGeneric.MyGoodMethod1(entity);
}
// and so on...
}
With this approach your logic will stay in logically separated classes.
In case somewhere you need only MyGoodGeneric method you don't need to provide whole giant class and will provide only the part needed.
In case some where you want introduce another implementation only for the MyCrazy methods you will not be forced to implement MyGood methods which you don't need in this case.
Extension method can be generic, not its container class:
public static class Extensions
{
public static T Method2<T>(this MyGeneric<T> generic)
{
}
}
So Partial classes were exactly what i was looking for. Thanks to #BradleyDotNET and #AliAbdelfattah
public partial class MyGeneric<T> : IMyGeneric<T> where T : IEntity
{
public MyGeneric(string stuff)
{
moreStuff(stuff);
}
//.. other stuff
}
in MyGenericGood.cs
public partial class MyGeneric<T> where T : IEntity
{
public void MyGoodMethod1(T entity)
{
//does good stuff with the generic..
}
public T MyGoodMethod2()
{
//does other good stuff with the generic..
}
}
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() );
}
}
I am using entity framework to generate a 'CClass' entity as below:
public partial class CClass: EntityObject
{
#region Factory Method
#region Primitive Properties
}
My rest of the partial class implementation is
public partial class CClass : IDemoralize
{
public Value xValue { get; set; }
public void IDemoralize.Demoralize()
{
// implementation
}
public void IDemoralize.Demoralize(Func<IDemoralize, bool> CustomDemoralization)
{
bool success = CustomDemoralization(this);
if (!success)
throw new ApplicationException();
}
public void IDemoralize.WriteModel()
{
// implementation
}
public void IDemoralize.WriteModel(Func<IDemoralize, bool> Write)
{
bool success = Write(this);
if (!success)
throw new ApplicationException();
}
}
Now since two methods listed below here does have common implementation across the whole design I want to move them to a base class called DemoralizeBase, so if code needs change then the consistency becomes manageable.
// in DemoralizeBase
public void Demoralize(Func<IDemoralize, bool> CustomDemoralization)
{
//implementation
}
public void WriteModel(Func<IDemoralize, bool> Write)
{
// implementation
}
Is there a way to do this or I should go with the existing design?
You could write those as extension methods:
public static class Demoralize {
public static void Demoralize(this IDemoralize obj,
Func<IDemoralize, bool> CustomDemoralization) {...}
public static void WriteModel(this IDemoralize obj,
Func<IDemoralize, bool> Write) {...}
}
This will then work as though it were an instance method, i.e.
var foo = new CClass();
foo.Demoralize(...);
One thing to watch: when calling extension methods on the current instance, the this. (which is usually optional) is required, i.e.
Demoralize(...); // does not work
this.Demoralize(...); // works
I would go for some dependency injection here.
IDemoralize defines 4 methods, 2 of them have common implementation across your framework.
What I would do is: extract a new interface from IDemoralize, and add a dependency to an object that implements that interface into CClass.
public interface IDemoralizeBase
{
void Demoralize(Func<IDemoralize, bool> CustomDemoralization);
void WriteModel(Func<IDemoralize, bool> Write);
}
Add an object IDemoralizeBase to CClass, and define a constructor that lets you inject the dependency
public class CClass : IDemoralize
{
public IDemoralizeBase MyDemoralizer {get; private set;}
public CClass(IDemoralizeBase basicDemoralizer)
{
MyDemoralizer = basicDemoralizer;
}
public void Demoralize(Func<IDemoralize, bool> CustomDemoralization)
{
MyDemoralizer.Demoralize(CustomDemoralization);
}
public void WriteModel(Func<IDemoralize, bool> Write)
{
MyDemoralizer.WriteModel(Write);
}
}
This will let you create one or n classes that implement IDemoralizeBase, so that, in case you get some special implementation in some special case, you can inject a special dependency.
Cheers,
Raphael