正如标题所述,我有一个仅将其命名为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 */
}
答案 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";
}