How to return Type T to an interface in C #?

I have an interface like this:

public interface IUser{ //some properties here T ToDerived(User u); } 

I'm new to interface design, so this is what I'm trying to accomplish. I will have a base class

 public class User 

which does NOT implement the above interface. Then I will have a derived class

 SalesUser : User, IUser { //no properties needed because they exist in the User class SalesUser ToDerived(User u) { //code for converting a base User to a derived SalesUser } } 

I would like to write the ToDerived (User u) function in the SalesUser class, but in the interface I do not know how to define this as a declaration of the ToDerived method, which now does not compile in the interface.

Hope this makes sense.

+6
source share
3 answers
 public interface IUser<T> where T : User { //some properties here T ToDerived(User u); } SalesUser : User, IUser<SalesUser> { //no properties needed because they exist in the User class SalesUser ToDerived(User u) { //code for converting a base User to a derived SalesUser } } 

Not sure if this is what you want, but I have added a generic type restriction on the interface to ensure that the generic User type is or inherited from it.

+14
source

Oded's answer solves the compilation problem by letting you define a ToDerived method that satisfies the interface. However, as I said in a comment, I'm not quite sure if this is the best implementation.

The main problem that I am facing is that such conversion methods are usually needed in a static context. You do not have an instance of SalesUser; you want, and you have a User, so you call the method in a static context ( SalesUser.ToDerived(myUser) ), and you get SalesUser (the method will have a more suitable name FromUser () or similar). The method specified in the interface requires that you already have SalesUser in order to convert the user to SalesUser. The only situation I can think of in which you really need an existing SalesUser is a "partial clone"; You create a new instance of SalesUser using information from both the user transferred and from the SalesUser to which you are calling the method. In all other cases, you either don’t need SalesUser (conversions that should be static, as indicated), or you don’t need a user (the clone or deep copy method that creates a new instance with the same data as the instance, on which you called the method).

In addition, users of your class must be aware that they must call ToDerived () in order to convert from user to SalesUser. Typically, a C # programmer expects an explicit or implicit conversion to be available:

 public class SalesUser { public static explicit operator (User user) { //perform conversion of User to SalesUser } } //the above operator permits the following: mySalesUser = (SalesUser)myUser; 

... OR, without receiving a conversion operator, one would expect him to be able to build SalesUser using User:

 public class SalesUser:IUser { public SalesUser(User user) { //initialize this instance using the User object } } //the above allows you to do this: mySalesUser = new SalesUser(myUser); //and it also allows the definition of a method like this, //which requires the generic to be an IUser and also requires a constructor with a User public void DoSomethingWithIUser<T>(User myUser) where T:IUser, new(User) { //...which would allow you to perform the "conversion" by creating a T: var myT = new T(myUser); } 

Now static members do not satisfy interface definitions, and interfaces cannot define static elements or constructor signatures. This tells me that the IUser interface should not try to define a conversion method; instead, methods that need some kind of IUser can simply specify this, and the user can provide the implementation as needed without an implementation that needs to know that it can convert to itself.

+3
source

Remember that an interface defines a class and its members without providing any implementation, yo can create an interface, but the interface must have an implementation class.

0
source

Source: https://habr.com/ru/post/912777/


All Articles