Scratching my bald patch....I have a generic Interface
interface IGenericInterface<T>
{
T GenericTypeProperty {get; set;}
void PerformService();
}
I have server classes that implement the generic interface and do some stuff
public class ServeRich : IGenericInterface<RichPeople>
{
RichPeople GenericTypeProperty {get; set;}
void PerformService() { //Serving the rich }
}
public class ServePoor : IGenericInterface<PoorPeople>
{
PoorPeople GenericTypeProperty {get; set;}
void PerformService() { //Serving the Poor }
}
Then I have a Service class as follows that I want to invoke and assign one of the server classes to and invoke PerformService()
public class ServeThem
{
//This is where I am trying to figure out how to do this
IGenericInterface<T<-??> Server {get; set;}
}
I want to eventually create the Service class and invoke the perform service method on Server....something like this
main()
{
ServeThem service= new ServeThem();
service.Server = new ServePoor(); //This will be resolved by Ninject
service.Server.PerformService();
}
My problem is in IGenericInterface<T<-??> Server {get; set;}
IGenericInterface<T<-??> Server {get; set;}
. I am trying to figure out how to declare Server
property as a generic interface type that can be assigned an object of a class that implements that interface of a particular type. It seems that for declaring IGenericInterface<type>
, an actual concrete type has to be mentioned. I tried adding a passedInType
property and using typeof(passedInType)
but that throws an exception.
How would I declare a property as a generic interface type? Is this even possible.
It seems that you don't use the GenericTypeProperty
in your service, so you can move the PerformService
method to a non-generic interface and use this interface in the Service class
interface INonGenericInterface
{
void PerformService();
}
interface IGenericInterface<T>: INonGenericInterface
{
T GenericTypeProperty {get; set;}
}
public class ServeThem
{
INonGenericInterface Server {get; set;}
}
You're looking for covariance .
// T is covariant (i.e. the "out" keyword)
public interface IGenericInterface<out T>
{
// Check that I removed the setter. T wouldn't be covariantly valid
// if it could be set...
// BTW, this doesn't prevent an implementation to provide a setter.
T GenericTypeProperty { get; }
void PerformService();
}
Now turn your ServeThem
class to declare the whole property as IGenericInterface<object>
:
public class ServeThem
{
//This is where I am trying to figure out how to do this
IGenericInterface<object> Server {get; set;}
}
If making read-only the GenericTypeProperty
property isn't an option, then this approach won't work for you. Anyway, most of the times you can take advantage of variance replacing a setter with a constructor parameter:
public class ServeRich : IGenericInterface<RichPeople>
{
private readonly RichPeople _people;
public ServerRich(RichPeople people)
{
_people = people;
}
// C# 6 expression-bodied read-only property
public RichPeople GenericTypeProperty => _people;
public void PerformService() { //Serving the rich }
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.