- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
这个问题是关于类型转换中的"is"和“作为”以及CA1800 PostSharp规则。我想知道我认为的解决方案是否是最好的解决方案,或者它是否存在我看不到的任何问题。
我有这段代码(名为 OriginaL Code 并减少到最低限度)。 ValidateSubscriptionLicenceProducts 函数尝试通过强制转换并稍后检查一些内容(在//Do Whatever 中)来验证 SubscriptionLicence(可能有 3 种类型:Standard、Credit 和 TimeLimited)。
PostSharp 提示 CA1800:DoNotCastUnnecessarily。原因是我将同一对象两次转换为同一类型。此代码在最好的情况下将转换 2 次(如果它是 StandardLicence),在最坏的情况下将转换 4 次(如果它是 TimeLimited Licence)。我知道有可能使规则无效(这是我的第一种方法),因为这里对性能没有太大影响,但我正在尝试一种最佳方法。
//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”方法(复制在代码下方)。这个版本我认为它最少只投一次,最多投三个。 你觉得 improve 2 怎么样?有没有最好的方法?
最佳答案
在您的三个代码片段中,“改进 2”似乎是最好的一个。不过,我认为您可以通过一种完全消除类型转换需求的方式来改进您的设计。
将名为 ValidateProducts
的抽象方法添加到 SubscriptionLicence
并让每个子许可证实现特定于该特定类型许可证的逻辑。这样,您将业务逻辑与数据放在一起,从而避免 anemic domain model .
这样,您的方法的实现将只是:
private void ValidateSubscriptionLicenceProducts(SubscriptionLicence licence)
{
if(!licence.ValidateProducts())
throw new Exception("Failed to validate products");
}
此外,通过在基类上抽象方法,您强制执行每个“子许可证”来实现该方法,因此您无需检查任何内容。因此,即使将来添加了新类型的许可证,也永远不必更改 ValidateSubscriptionLicenceProducts
方法。
希望它有意义。
关于c# - 这个对 "PostSharp complains about CA1800:DoNotCastUnnecessarily"的修复是最好的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2598982/
我有一个包含许多项目的解决方案,我想禁用 Postsharp 进行调试构建,以减少本地开发人员的构建时间。有没有办法在不编辑每个项目文件的情况下做到这一点? 我知道这听起来像是一个坏主意,但我们只使用
我的 CI 构建服务器遇到问题,其中 PostSharp 导致构建失败,并显示以下消息:程序集“yada-yada.dll”使用未经许可的功能(基本功能)。 [...]。我们使用的是当前版本的 Pos
我可以指定 SkipPostSharp 常量来确保项目从 PS 进程的项目列表中排除。但我想反过来做。我希望 PS 假设它不应该处理我没有明确告诉它的任何内容。 这可以实现吗? 最佳答案 项目被Pos
依赖注入(inject)在 Postsharp 中不起作用。如何使方面可测试?我真的想避免创建具体的类来记录我的方面。 我不希望在单元测试方法时运行方面。如果我正在测试一种方法,我不希望触发日志记录方
是否有可能在 Postsharp 的编译期间找到程序集的项目文件夹/项目文件或输出路径,例如,在 CompileTimeInitialize 期间,当正在构建程序集时? 最佳答案 您可以在编译期间通过
我正在尝试修改 Postsharp 附带的示例跟踪应用程序,以便将跟踪应用于我的命名空间中的所有类,而无需显式地将 [QuickTrace] 放在每个类的顶部。我附上了截图。我究竟做错了什么 ?右键单
根据推荐的 PostSharp 最佳实践,我在我的所有项目中都包含了 PostSharp。但是,我在其中一些程序集中没有任何方面或其他转换;他们只是引用了其他确实有使用方面的项目。 在构建时,我收到以
刚刚从 nuget 包安装了 Postsharp 2.1,然后安装了 Phil Haack 的 NullGuard 包。 当我在类或方法级别添加 [EnsureNonNullAspect] 方面时,我
你如何得到参数姓名 的一种方法。这些示例向您展示了如何获取 值 参数,但不是 姓名 .我想看到 parma = 99, parmb = 1。不仅仅是 99, 1。 using System;
假设我有一个方面实现 IInstanceScopedAspect我将这个方面应用于类型中的方法。使用 FormatterServices.GetUninitializedObject 创建对象时如何初
我正在努力理解为什么要使用后编译器,例如 PostSharp ,是否需要? 我的理解是,它只是在原始代码中插入代码,那么为什么开发人员不自己编写代码呢? 我希望有人会说它更容易编写,因为您可以在方法上
是否可以使用 PostSharp 拦截类构造函数和析构函数调用?我想为类创建事件实例计数器。 最佳答案 您可以在构造函数和析构函数上使用 OnMethodBoundaryAspect。请注意,默认情况
我有几个项目,希望在多个项目中应用方面。我像这样使用多播属性: [assembly:MyProject.Aspects.NotifiableObject( AttributeTargetAss
创建了一个简单的类来测试 PostSharp 中的 OnExceptionAspect。 [Serializable] [AttributeUsage(AttributeTargets.Method
我有一个 MethodInterceptionAspect(PostSharp) 的实现但是当我在重写 OnInvoke 方法时,args.Method 为 null,我需要知道方法返回值类型, 有人
我创建了一个小的方面层次结构。示例: public abstract class MyBaseAspectAttribute : Aspect, IAspectProvider { ... p
我喜欢在跟踪级别上记录一些 Postsharp 消息。不幸的是,记录到这个级别没有输出。所有其他级别都在工作。与控制台或 NLog 后端或当我从其他类登录时的行为相同。 如何启用跟踪级别? App.x
在开始之前,我想澄清一下,我目前对 AOP 术语的理解如下...... 方面是 AOP 等同于 OOP 中的类。 通知是 AOP 等价于 OOP 中的方法。 切入点是 AOP 等价于 OOP 中的“使
我偶然发现了 PostSharp 的一个不可思议的良好性能行为。为了评估速度,我写了一个小程序,它会执行一个函数指定的次数,如果启用了 PostSharp,它会生成和删除几百个字符串,就在内存中(非固
我正在使用 postsharp 1.5 和 OnMethodBoundaryAspect 处理一个方面。我希望我的方面默认具有以下行为: 1 - 如果在类级别使用属性,则方面仅应用于 PUBLIC 方
我是一名优秀的程序员,十分优秀!