繁体   English   中英

基类中的C#泛型类型

[英]C# generic type in a base class

我正在编写一个具有一组协议缓冲区的系统(使用protobuf-net),我想在它们都继承的抽象类中定义类似的东西:

public byte[] GetBytes()

但是,协议缓冲区serealiser需要一个类型参数,是否有一些有效的方法来获取继承类的类型?

例:

public byte[] GetBytes()
    {
        using (MemoryStream stream = new MemoryStream())
        {
            Serializer.Serialize<T /* what goes here? */>(stream, this);
            return stream.ToArray();
        }
    }

只写“T”吧?

然后在你的班级声明中:

public class M<T>

- 编辑

然后当你继承它时:

public class Foo : M<Apple>

将基类定义为BaseClass<T> ,然后派生类将T替换为序列化器类型DerivedClass<SerializerType>

您还可以在类型参数上指定约束,例如

BaseClass<T> where T : SerializerBase

以下是您可以应用的约束类型的说明。

你可以通过反思来做到这一点,但是protobuf-net为你做了这件事。

只需将您的电话改为:

Serializer.NonGeneric.Serialize(stream, this /* Takes an object here */);

这通过在运行时通过反射构建泛型方法来工作。 有关详细信息,请检查代码( 此处的第二种方法 )。

你实际上并不需要任何特别的东西......因为protobuf-net尊重继承。 如果你有:

[ProtoInclude(typeof(Foo), 20)]
[ProtoInclude(typeof(Bar), 21)]
public abstract class MyBase {
    /* other members */

    public byte[] GetBytes()
    {
        using(MemoryStream ms = new MemoryStream())
        {
            Serializer.Serialize<MyBase>(ms, this); // MyBase can be implicit
            return ms.ToArray();
        }
    }
}
[ProtoContract]
class Foo : MyBase { /* snip */ }
[ProtoContract]
class Bar : MyBase { /* snip */ }

然后它会工作。 要序列化数据,它始终以base(contract)类型开始 ; 所以即使你做了Serializer.Serialize<Foo>(stream, obj) ,它要做的第一件事就是检测它有一个基类是一个契约,并切换到MyBase 在反序列化期间,它将识别正确的派生(具体)类型并使用它,因此您也可以使用DeserializeMyBase ,并且它将根据原始数据构建FooBar

因此,以下内容基本相同:

Serializer.Serialize<BaseType>(dest, obj);
...
BaseType obj = Serializer.Deserialize<BaseType>(source);

Serializer.Serialize<DerivedType>(dest, obj);
...
DerivedType obj = Serializer.Deserialize<DerivedType>(source);

这里的主要区别在于如何键入变量。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM