我在我的代码(Credentials)中的几个地方使用了一个类,有一个方法需要更多的数据,我想在一个类(ArchiveData)中包含原始(Credentials)类
因此,当我创建类时,我只想将较小类中的所有数据分配到较大的类中。这样做的最佳实践方法是什么?
这里有一个类似的问题Are class initializers possible in C#? 并且建议不要覆盖初始化属性。我不一定想要一个我只想要一个为我添加已知值的重载方法,这样我可以拥有更清晰的代码,但是给它一个重载将覆盖默认的初始化程序。
虽然在这种情况下我将始终拥有子类,因此在此示例中删除原始初始化程序很好。我可以看到我不希望这样的场景。
编辑:删除了堆栈溢出错误 主要问题是从各种方式中选择最佳的协议和利弊。"吃一个子类。"
以下代码:
期望的最终结果是使更大的类具有更小类的所有数据的简洁方法:
Credentials credentials = new Credentials("My User Name", "some password");
ArchiveData AD = new ArchiveData(credentials);
Console.Write(AD.credentials.UserID);
Console.Write(AD.credentials.password);
课程设置:
public partial class ArchiveData
{
public string DocumentType { get; set; }
public int RTKD { get; set; }
public string RTMSG { get; set; }
public Credentials credentials;
public ArchiveData(Credentials credentials)
{
this.credentials = credentials;
}
}
public class Credentials
{
public string userId { get; set; }
public string password { get; set; }
public Credentials(string userId, string password)
{
this.userId = userId;
this.password = password;
}
}
答案 0 :(得分:3)
继承应该形成“is-a”关系。所以你可以拥有Dog : Animal
因为狗是动物。在决定一个班级是否应该从另一个班级继承时,这不是唯一重要的因素,但这是一个很好的起点。
在这种情况下,很难说这是否属实。你能说“归档数据是一组凭证吗?”如果是这样,iamruss上面的回答可能是要走的路。但也许你想说“归档数据有一套凭证。” (或者,等效地“包含”)。在这种情况下,你可以这样做:
public class ArchiveData
{
public Credentials credentials {get; private set;}
public string userData
{
get
{
return this.userData;
}
set
{
this.userData = value;
}
}
//other properties here
public ArchiveData(Credentials credentials)
{
this.credentials = credentials;
}
}
public class Credentials
{
public string userId { get; set; }
public string password { get; set; }
public Credentials(string userId, string password)
{
this.userId = userId;
this.password = password;
}
}
现在,如果您想获取用户ID和密码,您的代码段将如下所示:
Credentials credentials = new Credentials("My User Name", "some password");
ArchiveData AD = new ArchiveData(credentials);
Console.Write(AD.credentials.UserID);
Console.Write(AD.credentials.password);
这是一种比继承更灵活,更轻量级的方法,因此最好了解何时应该选择继承,何时应该选择包含,并选择最好的包含。
答案 1 :(得分:1)
欢迎来到OOP世界!
public class ArchiveData : Credentials
{
public string userData
{
get
{
return this.userData;
}
set
{
this.userData = value;
}
}
//other properties here
public ArchiveData(string userId, string password) : base(userId, password) {}
}
public class Credentials
{
public string userId { get; set; }
public string password { get; set; }
public Credentials(string userId, string password)
{
this.userId = userId;
this.password = password;
}
}
答案 2 :(得分:1)
首先,你不应该从Credentials扩展,除非你真正想要的(根据Liskov替换原则)。你似乎想要做的就像这个Composite Object示例所示:
class Program
{
static void Main(string[] args)
{
var credentials = new Credentials("My User Name", "some password");
var AD = new ArchiveData(credentials);
Console.Write(AD.UserId);
Console.Write(AD.Password);
}
}
public class ArchiveData
{
private readonly Credentials myCredentials;
public string UserData { get; set; }
public string UserId
{
get
{
return this.myCredentials.UserId;
}
}
public string Password
{
get
{
return this.myCredentials.Password;
}
}
public ArchiveData(Credentials credentials)
{
if (credentials == null)
throw new ArgumentNullException();
this.myCredentials = credentials;
}
}
public class Credentials
{
public string UserId { get; set; }
public string Password { get; set; }
public Credentials(string userId, string password)
{
this.UserId = userId;
this.Password = password;
}
}
以这种方式执行此操作(与打破LSP相反)的一个好处是,您无法使用旧的ArchiveData实例提供ArchiveData的新实例,因为ArchiveData也不是凭据,因此,构造函数的有效参数。