public interface IBaseData
SubData SubData {get;set;}
public struct DataStruct1 : IBaseData
public SubData SubData {get;set;}
public struct DataStruct2 : IBaseData
public SubData SubData {get;set;}
public abstract class BaseClass<TStruct> where TStruct: IBaseData
public int Data1 {get;set;}
public int Data2 {get;set;}
public abstract TStruct ToDataStruct();
public abstract void ReadDataStruct(TStruct obj);
public class DerivedClass1 : BaseClass<DataStruct1>
public bool Data3 {get;set;}
public override DataStruct1 ToDataStruct()
public override void ReadDataStruct(DataStruct1 dataStruct)
this.Data1 = dataStruct.Data1;
this.Data2 = dataStruct.Data2;
this.Data3 = dataStruct.Data3;
public class DerivedClass2 : BaseClass<DataStruct2>
public int Data3 {get;set;}
public override DataStruct2 ToDataStruct()
public override void ReadDataStruct(DataStruct2 dataStruct)
this.Data1 = dataStruct.Data1;
this.Data2 = dataStruct.Data2;
this.Data3 = dataStruct.Data3;
public abstract class GenericBase<T, TStruct> where T : BaseClass<TStruct>, new() where TStruct : IBaseData
public void DoWork(string json)
var derivedClass = new T();
var dataStruct = JsonConvert.DeserializeObject<TStruct>(json);
derivedClass.ReadDataStruct(dataStruct);
Console.WriteLine("Work done!");
public string CreateJson(T derivedClass)
var dataStruct = derivedClass.ToDataStruct();
return JsonConvert.SerializeObject(dataStruct);
public class WorkerClass1 : GenericBase<DerivedClass1, DataStruct1>
public class WorkerClass2 : GenericBase<DerivedClass2, DataStruct2>
public static void Main()
var workerClass = new WorkerClass1();
var structJson = JsonConvert.SerializeObject((new DerivedClass1 {Data1 = 100, Data2 = 200, Data3 = true}).ToDataStruct());
workerClass.DoWork(structJson);