[英]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
。 在反序列化期間,它將識別正確的派生(具體)類型並使用它,因此您也可以使用Deserialize
與MyBase
,並且它將根據原始數據構建Foo
或Bar
。
因此,以下內容基本相同:
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.