代码之家  ›  专栏  ›  技术社区  ›  Bendom

用C#链式语法调用同一对象的两个方法

  •  0
  • Bendom  · 技术社区  · 6 年前

    myObject.Read().Open(param1);

    我会写字 myObject.Open(param1).Read() ; 它进行编译,但不执行Read()。

    // ; 确实执行,但它是作为StreamReader方法而不是ReadTheFile方法执行的。忽视与帮助。。。

    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 回复  |  直到 6 年前
        1
  •  1
  •   Steve    6 年前

    如果您想拥有像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();
    

        2
  •  1
  •   Ondřej Kubíček    6 年前

    如果您想在不访问类的情况下向类添加更多功能,可以使用扩展。例如,使用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();
    

    您可以添加更多方法,但不能覆盖实例方法,因此必须创建新名称或新签名。

        3
  •  0
  •   LukaszBalazy    6 年前

    使用简单的构建器(这太过分了),但您可以实现您想要的:

     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();
    }