Вызов двух методов одного и того же объекта в C # - цепочка, как синтаксис - PullRequest
0 голосов
/ 27 января 2019

Cosidering Я не могу изменить класс ReadTheFile, есть ли способ, как "связать" методы экземпляра, чтобы мне не приходилось ссылаться на myObject несколько раз? Я ищу что-то вроде myObject.Read().Open(param1);

Я могу написать myObject.Open(param1).Read(); который компилируется, однако Read () не выполняется.

// myObject.Open(param1).Read(); выполняется, но выполняется как метод StreamReader, а не как метод ReadTheFile. Не обращайте внимания на помощь VS ...

class TestT211
{
    static void Main(string[] args)
    {
        var myObject = new ReadTheFile();

        myObject.Read(myObject.Open(@"C:\file.txt"));          
    } 
}

public class ReadTheFile
{
    private int _lineCounter = 0;
    private string _lineOfText;

    public StreamReader Open(string path)
    {
        return new StreamReader(path);
    }

    public void Read(StreamReader sr)
    {
        while ((_lineOfText = sr.ReadLine()) != null) {
            Console.WriteLine(_lineOfText);
        }
    }
}

Ответы [ 3 ]

0 голосов
/ 27 января 2019

Используя простой конструктор (это излишне), но вы можете достичь желаемого:

 class TestT211
{
    static void Main(string[] args)
    {
        FileReaderBuilder.New.Open(@"C:\file.txt").Read();
    }
}

public class ReadTheFile
{
    private int _lineCounter = 0;
    private string _lineOfText;

    public StreamReader Open(string path)
    {
        return new StreamReader(path);
    }

    public void Read(StreamReader sr)
    {
        while ((_lineOfText = sr.ReadLine()) != null)
        {
            Console.WriteLine(_lineOfText);
        }
    }
}

public class FileReaderBuilder
{
    private readonly ReadTheFile _file;

    private StreamReader _streamReader;

    private FileReaderBuilder()
    {
        _file = new ReadTheFile();
    }

    public FileReaderBuilder Open(string path)
    {
         _streamReader = _file.Open(path);

        return this;
    }

    public FileReaderBuilder Read()
    {
        if (_streamReader == null)
        {
            throw new ArgumentNullException(nameof(_streamReader));
        }

        _file.Read(_streamReader);

        return this;
    }

    public static FileReaderBuilder New => new FileReaderBuilder();
}
0 голосов
/ 27 января 2019

Если вы хотите добавить больше функциональности в класс без доступа к нему, вы можете использовать расширения. Например, использовать ReadTheFile для чтения StreamReader.

public static class StreamReaderExtension
{
    public static StreamReader ReadEx(this StreamReader sr)
    {
        var readTheFile = new ReadTheFile();
        readTheFile.Read(sr);
        return sr;
    }
}

и чем звонить с

myObject.Open(@"C:\file.txt").ReadEx();

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

0 голосов
/ 27 января 2019

Если вы хотите иметь синтаксис, такой как Fluent API, вам нужно изменить какую-то точку вашего класса.Сначала вам нужно, чтобы Open возвращал текущий экземпляр, а затем используйте этот экземпляр для вызова Read.Но это предполагает, что вы сохраняете StreamReader как внутреннюю переменную класса

public class ReadTheFile : IDisposable
{
    private int _lineCounter = 0;
    private string _lineOfText;
    private StreamReader _sr = null;

    public ReadTheFile Open(string path)
    {
        _sr = new StreamReader(path);
        return this;
    }

    public void Read()
    {
        if(_sr == null) return;

        while ((_lineOfText = _sr.ReadLine()) != null) {
            Console.WriteLine(_lineOfText);
        }
    }

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }
    protected virtual void Dispose(bool disposing)
    {
        if (disposing) 
        {
            if(_sr != null) 
            {
               _sr.Close();
               _sr = null;
            }
        }
    }   
}

, и теперь вы можете написать

 using(ReadTheFile myObject = new ReadTheFile())
      myObject.Open(@"C:\file.txt").Read();

Обратите внимание, что наличие StreamReader между вашими внутренними переменными требует от васреализовать интерфейс IDisposable для правильного закрытия и удаления потока

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...