如何应用泛型约束接受多级继承C#



我正在寻找一种方法来支持泛型类型约束的多级继承。

通用通用接口

public interface ICommon<T>
{
T OrignalData {get;set;}
string ChangeJson {get;set;}
T Merged {get;set;}
void Inject();
}

公共基类实现ICommon

public class Base <T>: ICommon<T>
{
public T OrignalData {get;private set;}
public string ChangeJson {get;set;}
public T Merged {get;private set;}
public void Inject(T orignal)
{
if (orignal == null)
return;

var settings = new JsonSerializerSettings
{
ObjectCreationHandling = ObjectCreationHandling.Auto
};
dynamic merged = orignal.Clone();
JsonConvert.PopulateObject(this.ChangeJson, merged, settings);
this.Merged  = merged;
this.Orignal = orignal;
}
}

部门类继承基类

public class Deparment : Base<Deparment>
{
}

组织部门类继承Deparment

public class OrgnizationDepartment : Deparment
{
}

类视图预期ICommon必须在传递的调用上实现

public class View<T> where T : ICommon<T>
{
//This class is totally dynamic to visualize any json data along with  old and new value of requested json for any class like department or org..
}

测试

public class Test
{
public void TestConstraint()
{
//No error 
var deptView = new View<Deparment>();
//Error as Base not directly implemented on OrgnizationDepartment 
var orgView = new View<OrgnizationDepartment>();
}
}

我如何定义我的约束,应该支持多级。

解决这一问题的一个方法是"组合而非继承";。

这里有一个天真的例子,它仍然相对接近您的代码:

using System;
using Newtonsoft.Json;

public class Program
{
public static void Main()
{
//No error 
var deptView = new View<Deparment>();
//Formerly Error 
var orgView = new View<OrgnizationDepartment>();
}
}
public interface ICommon<T> where T : ICloneable
{
// returns a tuple
(T,T,string) Inject(T original, string change);
}
public class Base <T>: ICommon<T> where T : ICloneable
{
// we can reuse this...
private readonly JsonSerializerSettings  settings = new JsonSerializerSettings
{
ObjectCreationHandling = ObjectCreationHandling.Auto
};
public (T,T,string) Inject(T original, string change)
{
if (original is null)
return default;

// this forces T to implement ICloneable ... just saying...
dynamic merged = original.Clone();

JsonConvert.PopulateObject(change, merged, settings);
return (original, merged, change);
}
}
public class Deparment : ICloneable, ICommon<Deparment>
{
// could also be created in ctor. Maybe use Ctor injection.
private readonly Base<Deparment> common = new Base<Deparment>();
public object Clone(){return this;} // this is of course nonsense. Clone properly! I did this to avoid dotnetfiddle screaming at me.
public (Deparment, Deparment, string) Inject(Deparment original, string change){
return common.Inject(original, change);
}
}
public class OrgnizationDepartment : ICloneable, ICommon<OrgnizationDepartment>
{
private readonly Base<OrgnizationDepartment> common = new Base<OrgnizationDepartment>();
public object Clone() {return this;}
public (OrgnizationDepartment, OrgnizationDepartment, string) Inject(OrgnizationDepartment original, string change){
return common.Inject(original, change);
}
}

相关内容

  • 没有找到相关文章

最新更新