C#类的继承,接口和实例化

时间:2018-07-16 07:05:08

标签: c# .net-core

我有一个像这样的基类

public class CamelClient : ICamelClient
{
    protected HttpClient _Client { get; set; }

    protected readonly string _BaseAddress;

    protected readonly string _TokenEndpoint;

    protected readonly string _ClientId;

    protected readonly string _Secret;

    public Contacts Contacts { get; set; }

    public Auth Auth { get; set; }

    public CamelClient(string baseAddress, string tokenEndpoint, string clientId, string secret)
    {
        _BaseAddress = baseAddress;
        _TokenEndpoint = tokenEndpoint;
        _ClientId = clientId;
        _Secret = secret;

        _Client = new HttpClient();
        _Client.BaseAddress = new Uri(_BaseAddress);

        Auth = new Auth(_BaseAddress, _TokenEndpoint, _ClientId, _Secret);
        Contacts = new Contacts(_BaseAddress, _TokenEndpoint, _ClientId, _Secret);
    }
}

它的界面看起来像这样

public interface ICamelClient
{
    Contacts Contacts { get; set; }

    Auth Auth { get; set; }
}

问题是当在基类构造函数中实例化Contacts和Auth时,我遇到了一个无限循环,因为派生类调用了基构造函数,最终导致了堆栈溢出错误。

有人知道我该如何使用它,因为如果我不实例化Contacts和Auth类,则它可以工作,但是当我尝试使用时,它们为null?

Contact类看起来像这样

public class Contacts : CamelClient
{
    public Contacts(string baseAddress, string tokenEndpoint, string clientId, string secret) : base(baseAddress, tokenEndpoint, clientId, secret)
    {
    }
}

Auth类看起来像这样

public class Auth : CamelClient
{
    public Auth(string baseAddress, string tokenEndpoint, string clientId, string secret) : base(baseAddress, tokenEndpoint, clientId, secret)
    {
    }
}

更改了我的代码,它现在似乎可以工作了。

public class CamelClient : ICamelClient
{
    public HttpClient _Client { get; set; }

    public readonly string _BaseAddress;

    public readonly string _TokenEndpoint;

    public readonly string _ClientId;

    public readonly string _Secret;

    public Contacts Contacts { get; }

    public Auth Auth { get; }

    public CamelClient(string baseAddress, string tokenEndpoint, string clientId, string secret)
    {
        _BaseAddress = baseAddress;
        _TokenEndpoint = tokenEndpoint;
        _ClientId = clientId;
        _Secret = secret;

        _Client = new HttpClient();
        _Client.BaseAddress = new Uri(_BaseAddress);

        Auth = new Auth(this);
        Contacts = new Contacts(this);
    }

public interface ICamelClient
{
    Contacts Contacts { get; }

    Auth Auth { get; }
}

 public class Auth
{
    private readonly CamelClient _CamelClient;

    public Auth(CamelClient camelClient) => _CamelClient = camelClient;
}

public class Contacts
{
    private readonly CamelClient _CamelClient;

    public Contacts(CamelClient camelClient) => _CamelClient = camelClient;
}

1 个答案:

答案 0 :(得分:1)

您似乎正在创建一些递归数据结构(如果我对"CommonJS"Contacts源自Auth的假设是正确的。

在这种情况下,如果您认为此模型已正确建模 1 ,则可能会将CamelClientContacts属性更改为只读属性由 lazy-initialized 支持字段返回。这可以很简单:

Auth

public class CamelClient : ICamelClient { //... private Contacts _contacts; public Contacts Contacts { get { if(_contacts == null) { _contacts = new Contacts(_BaseAddress, _TokenEndpoint, _ClientId, _Secret); } return _contacts; } } 相同。但是,这不是线程安全的。如果需要的话,我可能会建议后备字段使用Lazy<T>并在构造函数中进行适当的初始化


1 在这种情况下,消费者可以在任何给定实例上进行Auth等操作,似乎是有问题的。