类初始化器C#

时间:2014-05-22 08:02:05

标签: c# class initialization subclass

我在我的代码(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;
    }
}

3 个答案:

答案 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也不是凭据,因此,构造函数的有效参数。