如何创建一个“部分继承”另一个类或仅实现另一个类的成员和函数的类?

时间:2019-07-02 01:57:49

标签: c# inheritance

正如标题所述,我有一个仅将其命名为User的类,该类必须实现另一个固定类UserData的某些属性,但不是全部。但是,如果我直接使User继承UserData是行不通的,因为UserData中有些虚函数在User中是不必要的。那我该怎么办?

此外,由于业务逻辑的某些限制,我不会让UserData继承User,并且 UserData不应被修改或实现任何接口。

UserData

public class UserData
{
    private string _aS;
    public string AS
    {
        get { return _aS; }
        set { _aS = value; }
    }

    private string _bS;
    public virtual string BS
    {
        get { return _bS; }
        set { _bS = value; }
    }

    private string _cS;
    public virtual string CS
    {
        get { return _cS; }
        set { _cS = value; }
    }
}

用户

public class User
{
    private string _aS;     // Same as Daddy's
    public string AS
    {
        get { return _aS; }
        set { _aS = value; }
    }

    private string _bS;    // Same as Daddy's
    public virtual string BS
    {
        get { return _bS; }
        set { _bS = value; }
    }

    /* _cS should not be included in Baby */
}

1 个答案:

答案 0 :(得分:2)

C#使用接口建立通用属性和方法。

使用定义两个类的公共元素的接口。

public Interface UserInfo
{

    string AS {get; set;}

    string BS {get; set;}
}

您仍然可以使用基类,它必须是列表中的第一个基类,即在“:”之后。

public class UserData: UserInfo
public class User: UserInfo

由于这两个类已经已经实现了接口,因此除了从接口派生它们外,没有其他任何更改。

编辑

由于UserData类不能被修改(无论出于何种原因,通过API外部定义或公开公开)并且不是sealed,因此可以从中派生一个类并添加界面:

public class UserData1: UserData, UserInfo
{
// since the base class already implements the public properties as defined 
// in the interface, no implementation is required here

// however any defined constructors in the base class must be present here:
    // repeat per constructor
    public UserData1() : base() // add parameters: UserData1(int i):base(i)
    {
      // this can be left empty
    }
}

一个完全虚构的用例:

假设:

BusinessLogic.UserData传递给方法的方式为:

List<BusinessLogic.UserData> userData。和单个BusinessLogic.UserData值以确保完整性。

已经实例化并填充的类级别数组可以作为public User[] users使用。

这还需要“使用System.Linq;”进行批量类型转换。

public void ProcessAll(List<BusinessLogic.UserData> userData,BusinessLogic.UserData single)
{
   List<UserInfo> AllData = new List<UserInfo>();

   AllData.AddRange(userData.ConvertAll(new Converter<BusinessLogic.UserData, UserInfo>(i => i as UserData1))); 
   AllData.AddRange(users);
   // cast the single and add it to the list
   AllData.Add((UserInfo)((UserData1)single));// note the extra cast
   foreach(var user in AllData)
   {      
 //note CS is not available from AllData since it is not defined in the interface
      // not the most elegant code, but proves the point
      Console.WriteLine("AS=" + user.AS + " BS=" + user.BS);
   }
   //Let us replace the first element in userData with itself from AllData does nothing, but shows how to do this.
   if(AllData[0] is BusinessLogic.UserData)
//since add order is maintained in a list this if is not needed.
      userData[0] = (BusinessLogic.UserData)AllData[0];

   // since BusinessLogic.UserData is a reference type(class not struct) we can modify CS, but only if it is cast back to BusinessLogic.UserData first
   if(AllData[0] is BusinessLogic.UserData)
         ((BusinessLogic.UserData)AllData[0]).CS="Hello World";
}