如何将MemoryStream分配给继承自MemoryStream的自定义类

问题描述 投票:0回答:1

我有类MemoryStream2,它继承自MemoryStream,唯一的区别是它引入了一个新变量——引用id。现在我遇到一种情况,某个函数返回 MemoryStream,我需要将其转换/分配给 MemoryStream2。

public class MemoryStream2 : System.IO.MemoryStream
{
    public string ReferenceId = "";
    public MemoryStream2() : base() { }
    public MemoryStream2(byte[] buffer) : base(buffer) { }
    public MemoryStream2(System.IO.MemoryStream ms)
    {

        this.ReferenceId = DateTime.Now.ToString();
        this = ms;
    }
}

但是,

(System.IO.MemoryStream)this = ms;
是一个错误:

无法分配给“this”,因为它是只读的

(System.IO.MemoryStream)this = ms;
也不正确:

赋值的左侧必须是变量

那么我该怎么做呢?如何将标准 MemoryStream 分配给自定义 MemoryStream,最好不要将数据从一个流重新加载/复制到另一个流?

谢谢你

c# inheritance
1个回答
0
投票

组合几乎肯定是比继承更好的选择。即

public class MemoryStream2(MemoryStream Stream, string ReferenceId)
{
    public MemoryStream2(MemoryStream stream) : this(stream, DateTime.Now.ToString()){}
}

您还可以使用值元组来创建数据对,而无需创建新的显式类型,即

(MemoryStream Stream, string ReferenceId)
。继承有几个缺点,包括与基类的强耦合,因此在大多数情况下组合是首选

可以使用委托模式。这可能是一种有用的模式,但最适合相当小的接口。它并不真正适合

MemoryStream
,因为它并不是真正设计用于继承的。它可以与
Stream
一起使用,但由于方法数量众多,这也不理想:

public class MemoryStream2(MemoryStream Stream, string ReferenceId) : Stream
{
    public MemoryStream2(MemoryStream stream) : this(stream, DateTime.Now.ToString()){}
    public override void Flush() => Stream.Flush();
    public override long Seek(long offset, SeekOrigin origin) => Stream.Seek(offset, origin);
    public override void SetLength(long value) => Stream.SetLength(value);
    public override int Read(byte[] buffer, int offset, int count) => Stream.Read(buffer, offset, count);
    public override void Write(byte[] buffer, int offset, int count) => Stream.Write(buffer, offset, count);
    public override bool CanRead => Stream.CanRead;
    public override bool CanSeek => Stream.CanSeek;
    public override bool CanWrite => Stream.CanWrite;
    public override long Length => Stream.Length;
    public override long Position
    {
        get => Stream.Position;
        set => Stream.Position = value;
    }
}

如果绝对必要,您可以提取后备缓冲区并将其用作新流的缓冲区,但这不是我建议的做法,因为

GetBuffer
可能会失败:

public class MemoryStream2 : MemoryStream
{
    public string ReferenceId = "";

    public MemoryStream2(MemoryStream stream) : base(stream.GetBuffer())
    {
        this.SetLength(stream.Length);
        this.Position = stream.Position;
        this.ReferenceId = DateTime.Now.ToString();
    }
}

您还可以从现有流中复制数据,但似乎没有必要创建所有数据的完整副本,只是为了将其与引用 ID 相关联。

© www.soinside.com 2019 - 2024. All rights reserved.