。NET Core中的派生基类派生类

问题描述 投票:0回答:1

我想创建一个类来调用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;
}

[我看到了另外两个帖子(Convert base class to derived classthis one),我知道我无法按照自己的方式进行投射。然后我就是我的延伸]

/// <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# .net-core base-class .net-core-3.1
1个回答
0
投票

您不能cast(不会出错)将表达式返回/包含基类实例给任何继承者(如果该实例实际上没有继承)。强制转换为docs状态是编译器试图在运行时执行显式转换的尝试。另外,正如您提到的,您不能实现自定义类或自定义类的自定义显式转换。您正在寻找的是映射,并且为此提供了很多库,例如但不限于AutomapperMapsterExpressMapper

© www.soinside.com 2019 - 2024. All rights reserved.