I have a situation where I want to create an instance of a class depending on the implementation of the interface passed in as a parameter.
public interface IFooParameters
{
int Id { get; }
}
public interface IFooParametersAdditional
{
int AnotherProperty { get; }
}
public class FooBarParameters : IFooParameters
{
public int Id { get; set; } = 1;
public int Bar { get; set; } = 42;
}
public class FooBazParameters : FooBarParameters, IFooParametersAdditional
{
public int Baz { get; set; } = 55;
public int AnotherProperty { get; set; } = 99;
}
public interface IFoo<in TFooParameters>
where TFooParameters : IFooParameters
{
void DoStuff(TFooParameters parameters);
}
public class Bar : IFoo<FooBarParameters>
{
public void DoStuff(FooBarParameters parameters)
{
throw new System.NotImplementedException();
}
}
public class Baz : IFoo<FooBazParameters>
{
public void DoStuff(FooBazParameters parameters)
{
throw new System.NotImplementedException();
}
}
public class Another : IFoo<FooBazParameters>
{
public void DoStuff(FooBazParameters parameters)
{
throw new System.NotImplementedException();
}
}
public interface IFooFactory
{
IFoo<IFooParameters> GetInstance(IFooParameters parameters);
}
public class FooFactory : IFooFactory
{
public IFoo<IFooParameters> GetInstance(IFooParameters parameters)
{
if (parameters.Id == 1)
return new Bar(); // *** compiler error
if (parameters.Id == 2)
return new Baz(); // *** compiler error
return new Another(); // *** compiler error
}
}
// *** compiler error
is:
Error CS0266 Cannot implicitly convert type
'Bar'
to'IFoo<IFooParameters>'
. An explicit conversion exists (are you missing a cast?)
I'm not sure why I get this, as I thought derived implementations should (I would have thought) implicitly convert to their bases as Bar : IFoo<FooBarParameters>
, and FooBarParameters : IFooParameters
and this works (not bringing in generics):
public interface IBar { }
public class BarBar : IBar { }
public class Test
{
public IBar Thing()
{
return new BarBar();
}
}
The basic idea behind what I'm hoping to accomplish is, there are two potential implementations of IFooParameters
to pass into the FooFactory
, depending on the type and some validation, return an instance of IFoo<IFooParameter>
- I only care about returning the interface, as the underlying API is the same between all implementations of IFoo<IFooParameters
, though one implementation requires an additional property through FooBazParameters
.
I'm pretty new to generics, so I'm not sure if what I'm attempting to do is just completely wrong, or if I'm just missing something in the implementation. But any help and/or explanation to what's going on is appreciated.
Fiddle: https://dotnetfiddle.net/wjyLS7
Slightly changed with cast: https://dotnetfiddle.net/ZFQjCn