Несогласованная доступность: альтернатива общедоступному экземпляру частного вложенного класса - PullRequest
0 голосов
/ 03 июля 2018

Насколько я могу судить, этот тип конструкции не является обычной идиомой C #, но я пытаюсь максимально эмулировать интерфейс существующего API.

Моей первоначальной идеей было создание публичного экземпляра частного вложенного класса; однако, это дает ошибку о несовместимой доступности. В некоторой степени это имеет смысл, потребителю нужно увидеть определение класса, чтобы узнать, какие методы доступны для вызова.

Я бы хотел, чтобы библиотеку можно было использовать через следующий интерфейс:

Web3 web3 = new Web3(new HttpProvider("hostname"));
string apiVersion = web3.Version.Api;
string transactionResponse = Web3.Eth.SendTransaction(transaction);

Этот тип интерфейса является нормой для курса в Ruby или JavaScript, просто трудно понять, каким будет эквивалент C #.

Части вложенных классов будут зависеть от конкретного экземпляра Web3 (они зависят от информации, полученной от определенного узла RPC, к которому подключен)

Моя первая мысль реализовать это выглядела так:

public class Web3
{
    public readonly VersionInfo Version;
    private class VersionInfo
    {
        public readonly string Api = "2.0";
    }
}

Конечно, это дает непоследовательную ошибку доступности.

Автономный класс с внутренней видимостью не работает по той же причине.

Есть ли способ сделать это? Создать класс, экземпляр которого создается с внешним классом, но не может быть создан сам по себе?

1 Ответ

0 голосов
/ 03 июля 2018

Один из подходов состоит в том, чтобы сделать класс полностью закрытым и вернуть интерфейс:

private class VersionInfo : IVersionInfo
{
    public string Api { get { return "2.0"; } }
}

public interface IVersionInfo
{
    string Api { get; }
}

А затем просто измените определение в Web3 с VersionInfo на IVersionInfo.


В качестве альтернативы, вы можете просто сделать так, чтобы класс не ** мог быть создан или расширен вне библиотеки:

// Sealed to stop it being extended
public sealed class VersionInfo
{
    // Internal to stop it being instantiated outside the library
    internal VersionInfo()
    {
    }

    public readonly string Api = "2.0";
}

** Я говорю не могу, но решительный человек может создать экземпляр, используя отражение. Однако это не то, что вы можете предотвратить.

...