如何在c#类中使用两个构造函数时避免代码重复

  • 本文关键字:构造函数 两个 代码 c# .net
  • 更新时间 :
  • 英文 :


嗨,我有两个请求dto,其中一个是父请求,一个是子请求。

public class PaymentSupplierPaymentRequest
{
[JsonProperty("description")]
public string Description { get; set; }
[JsonProperty("amount")]
[Required]
public decimal Amount { get; set; }
[JsonProperty("currency")]
public string Currency { get; set; }
[JsonProperty("supplierid")]
[Required]
public string SupplierId { get; set; }
[JsonProperty("accountid")]
[Required]
public long AccountId { get; set; }
}
public class PaymentSupplierLitePaymentRequest: PaymentSupplierPaymentRequest
{
[JsonProperty("merchantCode")]
[Required]
public string MerchantCode { get; set; }
}

有两种类型的支付请求,一种需要商家代码,另一种不需要商家代码。根据请求,我有另一个类,它使用两个构造函数来处理传入请求的数据。

private readonly string _merchantCode;
private readonly string _installationId;
private readonly string _version;
private readonly string _paymentMethodMaskCode;
private readonly string _orderDescription;
private readonly long _amount;
private readonly string _currency;
private readonly string _email;
private const byte Exponent = 2;
private readonly string _orderCode;
public GemPayPaymentRequestBuilder(PaymentSupplierLitePaymentRequest paymentRequest)
{
_amount = (long)(paymentRequest.Amount * (decimal)Math.Pow(10, Exponent));
_orderDescription = paymentRequest.Description;
_currency = paymentRequest.Currency;
_orderCode = $"{paymentRequest.AccountId}_{DateTime.UtcNow.Ticks}";
_merchantCode = paymentRequest.MerchantCode;
}
public GemPayPaymentRequestBuilder(PaymentSupplierPaymentRequest paymentRequest, string email, WorldPayMerchantConfig config)
{
_amount = (long)(paymentRequest.Amount * (decimal)Math.Pow(10, Exponent));
_orderDescription = paymentRequest.Description;
_currency = paymentRequest.Currency;
_orderCode = $"{paymentRequest.AccountId}_{DateTime.UtcNow.Ticks}";
_email = email;
_merchantCode = config.MerchantCode;
_installationId = config.InstallationId;
_version = config.Version;
_paymentMethodMaskCode = config.PaymentMethodMaskCode;
}

问题是,正如你在代码中看到的,我在两个构造函数中重复了某些局部变量的初始化。

_amount = (long)(paymentRequest.Amount * (decimal)Math.Pow(10, Exponent));
_orderDescription = paymentRequest.Description;
_currency = paymentRequest.Currency;
_orderCode = $"{paymentRequest.AccountId}_{DateTime.UtcNow.Ticks}";

有人有更干净的方法吗?我已经尝试对第二个构造函数使用构造函数继承,如下所示。

public GemPayPaymentRequestBuilder(PaymentSupplierLitePaymentRequest paymentRequest)
{
_amount = (long)(paymentRequest.Amount * (decimal)Math.Pow(10, Exponent));
_orderDescription = paymentRequest.Description;
_currency = paymentRequest.Currency;
_orderCode = $"{paymentRequest.AccountId}_{DateTime.UtcNow.Ticks}";
_merchantCode = paymentRequest.MerchantCode;
}
public GemPayPaymentRequestBuilder(PaymentSupplierPaymentRequest paymentRequest, string email, WorldPayMerchantConfig config) : this(paymentRequest)
{
_email = email;
_merchantCode = config.MerchantCode;
_installationId = config.InstallationId;
_version = config.Version;
_paymentMethodMaskCode = config.PaymentMethodMaskCode;
}

但是这不起作用,因为使用: this(paymentRequest)会抛出转换错误,因为它不能从PaymentSupplierPaymentRequest转换为PaymentSupplierLitePaymentRequest。什么好主意吗?

只使用构造函数

最简单的方法是从不同的构造函数调用: this(因为PaymentSupplierLitePaymentRequest继承了PaymentSupplierPaymentRequest,而不是相反),但是您需要在第二个构造函数中处理其他参数并更改代码:

public GemPayPaymentRequestBuilder(PaymentSupplierLitePaymentRequest paymentRequest) : this(paymentRequest, null, null)
{
_merchantCode = paymentRequest.MerchantCode;
}
public GemPayPaymentRequestBuilder(PaymentSupplierPaymentRequest paymentRequest, string email, WorldPayMerchantConfig config)
{
_amount = (long)(paymentRequest.Amount * (decimal)Math.Pow(10, Exponent));
_orderDescription = paymentRequest.Description;
_currency = paymentRequest.Currency;
_orderCode = $"{paymentRequest.AccountId}_{DateTime.UtcNow.Ticks}";
_email = email;
if (config != null)
{
_merchantCode = config.MerchantCode;
_installationId = config.InstallationId;
_version = config.Version;
_paymentMethodMaskCode = config.PaymentMethodMaskCode;
}
}

或者另一种方法-您可以创建非公共构造函数来初始化公共数据并从公共数据调用它(我认为代码比上面的方法更干净,并且您有单独的地方初始化公共属性,没有nulls和ifs):

// protected (only for common data) and PaymentSupplierPaymentRequest as parameter
protected GemPayPaymentRequestBuilder(PaymentSupplierPaymentRequest paymentRequest) 
{
_amount = (long)(paymentRequest.Amount * (decimal)Math.Pow(10, Exponent));
_orderDescription = paymentRequest.Description;
_currency = paymentRequest.Currency;
_orderCode = $"{paymentRequest.AccountId}_{DateTime.UtcNow.Ticks}";
}
public GemPayPaymentRequestBuilder(PaymentSupplierLitePaymentRequest paymentRequest) : this((PaymentSupplierPaymentRequest)paymentRequest)
{
_merchantCode = paymentRequest.MerchantCode;
}
public GemPayPaymentRequestBuilder(PaymentSupplierPaymentRequest paymentRequest, string email, WorldPayMerchantConfig config) : this(paymentRequest)
{
_email = email;
_merchantCode = config.MerchantCode;
_installationId = config.InstallationId;
_version = config.Version;
_paymentMethodMaskCode = config.PaymentMethodMaskCode;
}

Using separate method.

您可以创建单独的方法,其中包含的逻辑对于两种类型都是相同的:

private void InitializeCommonData(PaymentSupplierPaymentRequest paymentRequest)
{
_amount = (long)(paymentRequest.Amount * (decimal)Math.Pow(10, Exponent));
_orderDescription = paymentRequest.Description;
_currency = paymentRequest.Currency;
_orderCode = $"{paymentRequest.AccountId}_{DateTime.UtcNow.Ticks}";
}

你可以初始化属性/字段:

public GemPayPaymentRequestBuilder(PaymentSupplierLitePaymentRequest paymentRequest)
{
this.InitializeCommonData(paymentRequest);
_merchantCode = paymentRequest.MerchantCode;
}
public GemPayPaymentRequestBuilder(PaymentSupplierPaymentRequest paymentRequest, string email, WorldPayMerchantConfig config)
{
this.InitializeCommonData(paymentRequest);
_email = email;
_merchantCode = config.MerchantCode;
_installationId = config.InstallationId;
_version = config.Version;
_paymentMethodMaskCode = config.PaymentMethodMaskCode;
}

您可以始终传递基类并始终调用完整的构造函数:

public GemPayPaymentRequestBuilder(PaymentSupplierPaymentRequest paymentRequest)
: this(paymentRequest, null, null)
{
}
public GemPayPaymentRequestBuilder(PaymentSupplierPaymentRequest paymentRequest, string email, WorldPayMerchantConfig config)
{
_amount = (long)(paymentRequest.Amount * (decimal)Math.Pow(10, Exponent));
_orderDescription = paymentRequest.Description;
_currency = paymentRequest.Currency;
_orderCode = $"{paymentRequest.AccountId}_{DateTime.UtcNow.Ticks}";

_email = email;
var liteRequest = paymentRequest as PaymentSupplierLitePaymentRequest;
if (liteRequest != null)
{
_merchantCode = liteRequest.MerchantCode;
}
else if (config != null)
{
_merchantCode = config.MerchantCode;
}
if (config != null)
{
_installationId = config.InstallationId;
_version = config.Version;
_paymentMethodMaskCode = config.PaymentMethodMaskCode;
}
}
}

在完整的构造函数(管理所有可能的参数的构造函数)中,您可以尝试强制转换类。如果这个类是Lite,你可以设置它的属性。

相关内容

  • 没有找到相关文章

最新更新