簡體   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