这个问题是关于铸造中的“是”和“作为”以及关于CA1800 PostSharp规则的问题。我想知道我认为的解决方案是否是最好的解决方案,或者它是否有任何我看不到的问题。
我有这个代码(命名为原始代码并减少到最低相关)。ValidateSubscriptionLicenceProducts 函数尝试通过强制转换并稍后检查一些内容(在 //Do What 中)来验证 SubscriptionLicence(可能是 3 种类型:Standard、Credit 和 TimeLimited)。
PostSharp 抱怨 CA1800:DoNotCastUnnecessarily。原因是我将同一对象两次转换为同一类型。此代码在最佳情况下将转换 2 次(如果它是 StandardLicence),在最坏情况下将转换 4 次(如果它是 TimeLimited 许可证)。我知道有可能使规则无效(这是我的第一种方法),因为这里的性能没有太大影响,但我正在尝试一种最佳方法。
//Version Original Code
//Min 2 casts, max 4 casts
//PostSharp Complains about CA1800:DoNotCastUnnecessarily
private void ValidateSubscriptionLicenceProducts(SubscriptionLicence licence)
{
if (licence is StandardSubscriptionLicence)
{
// All products must have the same products purchased
List<StandardSubscriptionLicenceProduct> standardProducts = ((StandardSubscriptionLicence)licence).SubscribedProducts;
//Do whatever
}
else if (licence is CreditSubscriptionLicence)
{
// All products must have a valid Credit entitlement & Credit interval
List<CreditSubscriptionLicenceProduct> creditProducts = ((CreditSubscriptionLicence)licence).SubscribedProducts;
//Do whatever
}
else if (licence is TimeLimitedSubscriptionLicence)
{
// All products must have a valid Time entitlement
// All products must have a valid Credit entitlement & Credit interval
List<TimeLimitedSubscriptionLicenceProduct> creditProducts = ((TimeLimitedSubscriptionLicence)licence).SubscribedProducts;
//Do whatever
}
else
throw new InvalidSubscriptionLicenceException("Invalid Licence type");
//More code...
}
这是使用"as"的改进版本。不要抱怨 CA1800,但问题是它总是会投射 3 次(如果将来我们有 30 或 40 种类型的许可证,它可能会表现不佳)
//Version Improve 1
//Minimum 3 casts, maximum 3 casts
private void ValidateSubscriptionLicenceProducts(SubscriptionLicence licence)
{
StandardSubscriptionLicence standardLicence = Slicence as StandardSubscriptionLicence;
CreditSubscriptionLicence creditLicence = Clicence as CreditSubscriptionLicence;
TimeLimitedSubscriptionLicence timeLicence = Tlicence as TimeLimitedSubscriptionLicence;
if (Slicence == null)
{
// All products must have the same products purchased
List<StandardSubscriptionLicenceProduct> standardProducts = Slicence.SubscribedProducts;
//Do whatever
}
else if (Clicence == null)
{
// All products must have a valid Credit entitlement & Credit interval
List<CreditSubscriptionLicenceProduct> creditProducts = Clicence.SubscribedProducts;
//Do whatever
}
else if (Tlicence == null)
{
// All products must have a valid Time entitlement
// All products must have a valid Credit entitlement & Credit interval
List<TimeLimitedSubscriptionLicenceProduct> creditProducts = Tlicence.SubscribedProducts;
//Do whatever
}
else
throw new InvalidSubscriptionLicenceException("Invalid Licence type");
//More code...
}
但后来我想了一个最好的。这是我正在使用的最终版本。
//Version Improve 2
// Min 1 cast, Max 3 Casts
// Do not complain about CA1800:DoNotCastUnnecessarily
private void ValidateSubscriptionLicenceProducts(SubscriptionLicence licence)
{
StandardSubscriptionLicence standardLicence = null;
CreditSubscriptionLicence creditLicence = null;
TimeLimitedSubscriptionLicence timeLicence = null;
if (StandardSubscriptionLicence.TryParse(licence, out standardLicence))
{
// All products must have the same products purchased
List<StandardSubscriptionLicenceProduct> standardProducts = standardLicence.SubscribedProducts;
//Do whatever
}
else if (CreditSubscriptionLicence.TryParse(licence, out creditLicence))
{
// All products must have a valid Credit entitlement & Credit interval
List<CreditSubscriptionLicenceProduct> creditProducts = creditLicence.SubscribedProducts;
//Do whatever
}
else if (TimeLimitedSubscriptionLicence.TryParse(licence, out timeLicence))
{
// All products must have a valid Time entitlement
List<TimeLimitedSubscriptionLicenceProduct> timeProducts = timeLicence.SubscribedProducts;
//Do whatever
}
else
throw new InvalidSubscriptionLicenceException("Invalid Licence type");
//More code...
}
//Example of TryParse in CreditSubscriptionLicence
public static bool TryParse(SubscriptionLicence baseLicence, out CreditSubscriptionLicence creditLicence)
{
creditLicence = baseLicence as CreditSubscriptionLicence;
if (creditLicence != null)
return true;
else
return false;
}
它需要更改 StandardSubscriptionLicence、CreditSubscriptionLicence 和 TimeLimitedSubscriptionLicence 类以具有“tryparse”方法(在下面的代码中复制)。这个版本我认为它最少只能投射一次,最多只能投射三个。改进2你怎么看?有没有最好的方法呢?