强制转换基类以派生 .NET Core 中的类



我想创建一个类来调用SQL Server中的存储过程。我正在使用 C# 和 .NET Core 3.1。所有存储过程都返回相同的结果,但在某些情况下,我必须执行更多活动,然后每个函数都有自己的基于基类的返回类型,在下面的代码中称为BaseResponse

public class BaseResponse
{
public int ErrorCode { get; set; }
public string Message { get; set; }
}
public class InvoiceResponse : BaseResponse
{
public bool IsPaid { get; set; }
}

然后,我有我BaseCall,它负责调用存储过程并返回BaseResponse

public async Task<BaseResponse> BaseCall(string procedureName, string[] params)
{
BaseResponse rtn = new BaseResponse();
// call SQL Server stored procedure
return rtn;
}

在另一个类中,我想使用派生类强制转换BaseResponse。为此,我认为我可以用派生类来投BaseResponse,但我错了。

public async Task<InvoiceResponse> GetInvoice(int id)
{
InvoiceResponse rtn = new InvoiceResponse();
BaseResponse response = BaseCall("myprocedure", null);
rtn = (InvoiceResponse)response;
// do something else
return rtn;
}

我看到了另外两篇文章(将基类转换为派生类和这个(,我知道我不能按照我想要的方式投射。然后我就是我的延伸

/// <summary>
/// Class BaseClassConvert.
/// </summary>
public static class BaseClassConvert
{
/// <summary>
/// Maps to new object.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="sourceobject">The sourceobject.</param>
/// <returns>T.</returns>
/// <remarks>
/// The target object is created on the fly and the target type
/// must have a parameterless constructor (either compiler-generated or explicit)
/// </remarks>
public static T MapToNewObject<T>(this object sourceobject) where T : new()
{
// create an instance of the target class
T targetobject = (T)Activator.CreateInstance(typeof(T));
// map the source properties to the target object
MapToExistingObject(sourceobject, targetobject);
return targetobject;
}
/// <summary>
/// Maps to existing object.
/// </summary>
/// <param name="sourceobject">The sourceobject.</param>
/// <param name="targetobject">The targetobject.</param>
/// <remarks>The target object is created beforehand and passed in</remarks>
public static void MapToExistingObject(this object sourceobject, object targetobject)
{
// get the list of properties available in source class
var sourceproperties = sourceobject.GetType().GetProperties().ToList();
// loop through source object properties
sourceproperties.ForEach(sourceproperty =>
{
var targetProp = targetobject.GetType().GetProperty(sourceproperty.Name);
// check whether that property is present in target class and is writeable
if (targetProp != null && targetProp.CanWrite)
{
// if present get the value and map it
var value = sourceobject.GetType().GetProperty(sourceproperty.Name).GetValue(sourceobject, null);
targetobject.GetType().GetProperty(sourceproperty.Name).SetValue(targetobject, value, null);
}
});
}
}

这段代码可以工作,我可以像这样使用它:

public async Task<InvoiceResponse> GetInvoice(int id)
{
InvoiceResponse rtn = new InvoiceResponse();
BaseResponse response = BaseCall("myprocedure", null);
response.MapToExistingObject(rtn);
// do something else
return rtn;
}

我的问题是:

  • 是否有更有效的方法在 .NET Core 中使用派生类强制转换基类?
  • 这是铸造的最佳实践吗?
  • 还有其他指导线吗?
  • 此过程使用Reflection。从性能的角度来看,这是实现这种演员阵容的正确和最便宜的方式吗?

如果该实例实际上没有继承基类实例,则无法将返回/包含基类实例的表达式强制转换为(而不会出错(该表达式(为了检查这一点,C#中有类型测试运算符(。强制转换为 docs 状态是编译器尝试在运行时执行显式转换。此外,正如您提到的,您无法实现从基类到基类的自定义显式转换。

你正在寻找(并试图做的事情(被称为映射,有很多库,包括但不限于Automapper,Mapster或ExpressMapper。

最新更新