如何解决如何应用泛型约束来接受多级继承 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>
{
}
OrgnizationDepartment 类继承了 Deparment
public class OrgnizationDepartment : Deparment
{
}
class View 期望 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,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,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,change);
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。