【问题标题】:Why base.method() does not calling base class method in C#?为什么 base.method() 不调用 C# 中的基类方法?
【发布时间】:2018-07-11 14:06:56
【问题描述】:

我有一个名为 TCPStream 的课程。它继承NetworkStream 类。 而NetworkStream继承Stream类即,

public class TCPStream : NetworkStream, IComparable<TCPStream>
{...}

public class NetworkStream : Stream
{...}

现在,Stream 类有一个函数 ReadAsync(,,,),并且该函数也在 TCPStream 类中被覆盖。

我的问题是:当我在 TCPStream 类中调用 base.ReadAsync(,,,) 时,它会一次又一次地执行自身...(不调用(父)Stream 类方法...)

因此,StackOverFlowException 是由于自调用而发生的..

我应该怎么做才能完成这项任务? 代码片段如下

 public override Task<int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
    {
        try
        {

            // int read_RetryCount = 0;
            // repeat till Complete Packet Received
            TimeSpan timeOutLimit = TimeSpan.MaxValue;
            if (CanTimeout)
                timeOutLimit = DateTime.Now.TimeOfDay + TimeSpan.FromMilliseconds(ReadTimeout);     // maxTimeOutLimit


                **// *** Here is Problem, base.ReadAsync(,,,) Not execute Parent's ReasAsync(,,,)***
                // *** After This Line, Function Execute itself Again..*****

                var length = base.ReadAsync(_localBuffer.Array, _localBuffer.Offset, _localBuffer.Count ).GetAwaiter().GetResult();

                Console.WriteLine("Total Bytes read = " + length);

        }
    }

【问题讨论】:

标签: c# stream networkstream


【解决方案1】:

现在你已经添加了代码,问题就很清楚了:

你有:

public override Task<int> ReadAsync(byte[] buffer, int offset, int count,
    CancellationToken cancellationToken)
{
    ...
     var length = base.ReadAsync(_localBuffer.Array,
         _localBuffer.Offset, _localBuffer.Count ).GetAwaiter().GetResult(); 
}

现在看ReadAsync(byte[],int,int)的默认实现:

public Task<int> ReadAsync(byte[] buffer, int offset, int count) => 
    this.ReadAsync(buffer, offset, count, CancellationToken.None);

您没有调用您要覆盖的相同方法 - 您调用了一个非常微妙的不同方法。 问题是您没有传递取消令牌。如果您只是更改为:

 var length = base.ReadAsync(_localBuffer.Array,
     _localBuffer.Offset, _localBuffer.Count, cancellationToken).GetAwaiter().GetResult();

它应该会消失。

但是请注意,您永远不应该像这样使用.GetAwaiter().GetResult()。更好的解决方案是将 async 修饰符添加到您的方法中,并使用:

 var length = await base.ReadAsync(_localBuffer.Array,
     _localBuffer.Offset, _localBuffer.Count, cancellationToken);

或者,去掉 while(true) 循环 - 它看起来非常错误 - 不要添加 async 修饰符,然后:

return base.ReadAsync(_localBuffer.Array,
     _localBuffer.Offset, _localBuffer.Count, cancellationToken);

【讨论】:

  • 亲爱的马克?为什么我们不能调用父类的另一个方法?使用 base.someAnotherMethod()??并且 ReadAsync() withOut cancelToken 也是 Parent 类中的一个方法
  • @FahadUsman 它确实是一种方法,但它是外部调用者便捷方法,而不是您作为Stream 的实施者 - 它的作用是:使用默认取消令牌调用当前的ReadAsync(byte[],int,int,CancellationToken) 方法(即您的方法)。
  • @HimBromBeere 所有这些都已经在这里讨论过......只是说'
  • 亲爱的@MarcGravell ...如果您注意到,我的函数也有4个参数,..如果我在调用时传递了3个参数,那么为什么我的函数会自行执行...?? ???以及为什么不给出错误之类的 MisMatch 参数等...
  • @FahadUsman 不,写base.ReadAsnyc时,你只提供三个参数。因此,来自Stream 的非虚方法被调用,它本身调用带有四个 参数的virtual 方法。在您的情况下,这是覆盖
猜你喜欢
  • 2014-07-17
  • 2012-05-31
  • 2017-10-31
  • 2013-07-17
  • 2010-12-29
  • 2011-10-30
  • 2023-03-05
  • 1970-01-01
  • 2015-07-12
相关资源
最近更新 更多