我将如何处理两个完全相同的 类 除了名称?
How would I process two classes that are exactly the same except by name?
我正在 Core 3.1 中编写服务。在我正在编写的服务中,我创建了一个连接到旧版 SOAP 服务的连接服务,该服务与甚至更旧的系统进行交互。 SOAP 服务提供基本的 CRUD 操作并使用 类 作为数据容器。问题是为服务引用生成的代码为具有完全相同属性的对象创建了单独的 partial
类。
public partial class REQUEST1
{
public string PropertyName {get; set;}
}
public partial class REQUEST2
{
public string PropertyName {get; set;}
}
我发现我在准备请求对象方面一遍又一遍地编写相同的代码。
private void SetProperties(MyClass parameters, REQUEST1 request)
{
request.PropertyName = parameters.MyParamValue;
}
private void SetProperties(MyClass parameters, REQUEST2 request)
{
request.PropertyName = parameters.MyParamValue;
}
我不想修改生成的代码,因为下次生成代码时,必须有人记得这样做。接口和基础 类 并不是真正的选项,因为它正在修改生成的代码。因此,我正在寻找有关如何编写一种方法的建议,该方法可以采用其中之一 类 并在不编写千篇一律的代码的情况下设置值。
更新:
所以这变得更加复杂。
在 create/update 服务中,我有复杂的对象。
public partial class ADDRESS
{
// Address Properties created by the service reference
}
public partial class PERSON
{
ADDRESS[] ADDRESSES { get; set;}
// Other properties created by the service reference
}
我可以为地址和人员创建界面,但这会产生另一个问题。
public interface IAddress
{
// Address properties
}
public interface IPerson
{
IAddress[] ADDRESSES {get;set;}
// Other properties
}
public partial class ADDRESS : IAddress
{
}
public partial class PERSON : IPerson
{
}
这会产生一个错误,指出 PERSON 没有实现成员 IAddress[] ADDRESSES,因为它没有正确的 return 类型。这是有道理的,但我不确定如何解决它。对于具有原始类型的单个对象,这种方法有效,但对于更复杂的类型,它似乎需要另一种解决方案。
如果您不想深入挖掘代码生成并添加接口或子 类 也许扩展方法可以解决问题 (Documentation) combined with a bit reflection :) Other SO Answer
你的情况:
public static class RequestExtensions
{
public static void SetProperty(this REQUEST1 request, YourClass parameters)
{
SetProperty(request, "PropertyName", parameters.MyParamValue;
}
public static void SetProperty(this object obj, string propertyName, object value)
{
// Very generic. Always try to not use reflection :)
// No exception handling or null checks here because of example code.
obj.GetType().InvokeMember(propertyName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.SetProperty, Type.DefaultBinder, obj, value);
}
}
在这里你可以看到你可以添加扩展方法到已经生成的类。另一种选择是直接使用 SetProperty
(不推荐)。
在我看来,最好的解决方案是深入挖掘生成器并添加接口或基础 类 以支持以所有其他方式对您的 类 进行通用访问,反射是您最好的朋友。
我建议使用部分 类 添加到 类 的接口。
public interface IRequest
{
string PropertyName {get; set;}
}
public partial class REQUEST1
{
public string PropertyName {get; set;}
}
public partial class REQUEST2
{
public string PropertyName {get; set;}
}
public partial class REQUEST1 : IRequest
{
}
public partial class REQUEST2 : IRequest
{
}
你可以有这样的方法
private void SetProperties(MyClass parameters, IRequest request)
{
request.PropertyName = parameters.MyParamValue;
}
如果您不想手动操作.........考虑
https://www.nuget.org/packages/automapper/
示例(当 属性 名称重叠时非常简单)
MapperConfigurationconfig = new MapperConfiguration(cfg => {
cfg.CreateMap<Request1, Request2>();
});
IMapper iMapper = config.CreateMapper();
Request1 source = new Request1();
Request2 destination = iMapper.Map<Request1, Request2>(source);
如果 属性 名称不完全匹配.....您调整“配置”。
这是另一篇文章:
https://www.infoworld.com/article/3192900/how-to-work-with-automapper-in-csharp.html
我正在 Core 3.1 中编写服务。在我正在编写的服务中,我创建了一个连接到旧版 SOAP 服务的连接服务,该服务与甚至更旧的系统进行交互。 SOAP 服务提供基本的 CRUD 操作并使用 类 作为数据容器。问题是为服务引用生成的代码为具有完全相同属性的对象创建了单独的 partial
类。
public partial class REQUEST1
{
public string PropertyName {get; set;}
}
public partial class REQUEST2
{
public string PropertyName {get; set;}
}
我发现我在准备请求对象方面一遍又一遍地编写相同的代码。
private void SetProperties(MyClass parameters, REQUEST1 request)
{
request.PropertyName = parameters.MyParamValue;
}
private void SetProperties(MyClass parameters, REQUEST2 request)
{
request.PropertyName = parameters.MyParamValue;
}
我不想修改生成的代码,因为下次生成代码时,必须有人记得这样做。接口和基础 类 并不是真正的选项,因为它正在修改生成的代码。因此,我正在寻找有关如何编写一种方法的建议,该方法可以采用其中之一 类 并在不编写千篇一律的代码的情况下设置值。
更新: 所以这变得更加复杂。 在 create/update 服务中,我有复杂的对象。
public partial class ADDRESS
{
// Address Properties created by the service reference
}
public partial class PERSON
{
ADDRESS[] ADDRESSES { get; set;}
// Other properties created by the service reference
}
我可以为地址和人员创建界面,但这会产生另一个问题。
public interface IAddress
{
// Address properties
}
public interface IPerson
{
IAddress[] ADDRESSES {get;set;}
// Other properties
}
public partial class ADDRESS : IAddress
{
}
public partial class PERSON : IPerson
{
}
这会产生一个错误,指出 PERSON 没有实现成员 IAddress[] ADDRESSES,因为它没有正确的 return 类型。这是有道理的,但我不确定如何解决它。对于具有原始类型的单个对象,这种方法有效,但对于更复杂的类型,它似乎需要另一种解决方案。
如果您不想深入挖掘代码生成并添加接口或子 类 也许扩展方法可以解决问题 (Documentation) combined with a bit reflection :) Other SO Answer
你的情况:
public static class RequestExtensions
{
public static void SetProperty(this REQUEST1 request, YourClass parameters)
{
SetProperty(request, "PropertyName", parameters.MyParamValue;
}
public static void SetProperty(this object obj, string propertyName, object value)
{
// Very generic. Always try to not use reflection :)
// No exception handling or null checks here because of example code.
obj.GetType().InvokeMember(propertyName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.SetProperty, Type.DefaultBinder, obj, value);
}
}
在这里你可以看到你可以添加扩展方法到已经生成的类。另一种选择是直接使用 SetProperty
(不推荐)。
在我看来,最好的解决方案是深入挖掘生成器并添加接口或基础 类 以支持以所有其他方式对您的 类 进行通用访问,反射是您最好的朋友。
我建议使用部分 类 添加到 类 的接口。
public interface IRequest
{
string PropertyName {get; set;}
}
public partial class REQUEST1
{
public string PropertyName {get; set;}
}
public partial class REQUEST2
{
public string PropertyName {get; set;}
}
public partial class REQUEST1 : IRequest
{
}
public partial class REQUEST2 : IRequest
{
}
你可以有这样的方法
private void SetProperties(MyClass parameters, IRequest request)
{
request.PropertyName = parameters.MyParamValue;
}
如果您不想手动操作.........考虑
https://www.nuget.org/packages/automapper/
示例(当 属性 名称重叠时非常简单)
MapperConfigurationconfig = new MapperConfiguration(cfg => {
cfg.CreateMap<Request1, Request2>();
});
IMapper iMapper = config.CreateMapper();
Request1 source = new Request1();
Request2 destination = iMapper.Map<Request1, Request2>(source);
如果 属性 名称不完全匹配.....您调整“配置”。
这是另一篇文章:
https://www.infoworld.com/article/3192900/how-to-work-with-automapper-in-csharp.html