6

我有一个这样的界面:

public interface IUser{
    //some properties here

    T ToDerived(User u);
}

我是界面开发的新手,所以这就是我想要完成的事情。我将有一个基类

public class User 

不实现上述接口。然后我会有一个派生类

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
    }
}

我想在 SalesUser 类中为 ToDerived(User u) 编写函数,但是在接口中,我不知道如何将其定义为我现在在接口中的 ToDerived 方法声明没有编译。

我希望这是有道理的。

4

3 回答 3

14
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
    }
}

不确定这是您想要的,但我在接口上添加了泛型类型约束以确保泛型类型是User或继承自它。

于 2012-04-09T18:56:24.830 回答
3

Oded的回答解决了编译问题,让你定义满足接口的ToDerived方法。但是,正如我在评论中所说,我不确定这是最好的实现。

我遇到的主要问题是在静态上下文中通常需要这样的转换方法。您没有 SalesUser 的实例;你想要一个,并且有一个用户,所以你在静态上下文中调用该方法(SalesUser.ToDerived(myUser)) 并且您得到一个 SalesUser (该方法更适合命名为 FromUser() 或类似名称)。您在界面中指定的方法要求您已经拥有一个 SalesUser 才能将 User 转换为 SalesUser。我能想到的唯一需要预先存在的 SalesUser 的情况是“部分克隆”;您正在使用来自传入的用户和调用该方法的 SalesUser 的信息创建一个新的 SalesUser 实例。在所有其他情况下,您要么不需要 SalesUser(转换,如前所述,它应该是静态的),要么不需要 User(产生新实例的“克隆”或“深拷贝”方法)与您调用该方法的实例相同的数据)。

此外,您的类的消费者必须知道他们必须调用 ToDerived() 才能执行从 User 到 SalesUser 的转换。通常,C# 程序员会期望显式或隐式转换可用:

public class SalesUser
{

    public static explicit operator (User user)
    {
        //perform conversion of User to SalesUser
    }

}

//the above operator permits the following:
mySalesUser = (SalesUser)myUser;

... 或者,如果转换运算符失败,则希望能够使用 User 构造 SalesUser:

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);
}

现在,静态成员不满足接口定义,接口不能定义静态成员或构造函数签名。这告诉我,IUser 接口不应该尝试定义转换方法;相反,需要某种 IUser 的方法可以简单地指定它,并且用户可以根据需要提供一个实现,而该实现不需要知道它可以转换为自身。

于 2012-04-09T19:59:52.833 回答
0

请记住,接口定义了一个类及其成员而不提供任何实现,您可以创建一个接口,但该接口必须具有实现类。

于 2012-04-09T19:05:13.390 回答