c# - 有没有一种方法可以简化检查值是某物的倍数而不是 0 的方法?
问题描述
我有这个代码:
if (Settings.Trk3 % 20 == 0 && Settings.Trk3 > 0)
// Do something
看起来可能有更好的编码方法,但我想不出该怎么做。有人有建议吗?
解决方案
如果它是您的代码库中的常见操作,我会使用扩展方法 - 但如果它是一次性检查,那么我会保留您的代码原样,因为您现有的代码清楚地表明意图并且因为大于零和模除法是不同的操作,应该分开。
也就是说 - 这是扩展方法的样子:
public static class IntegerExtensions
{
public static Boolean IsNonZeroMultipleOf( this Int32 value, Int32 divisor)
{
return ( value > 0 ) && ( value % divisor ) == 0;
}
}
用法:
if( Settings.Trk3.IsNonZeroMultipleOf( 20 ) )
{
// Do something.
}
关于性能:JIT 应该足够聪明,可以内联琐碎的非虚拟方法调用,尤其是对于纯函数,包括扩展方法,因此如果绝对必要,在紧密循环中使用此代码是安全的。(我认为没有[Pure]
必要使用该属性)。
但是,如果您想成为一个绝对糟糕的程序员,那么请使用带有隐式转换为/从Int32
和重载运算符的自定义结构。此代码(滥用)>>
操作员执行与IsNonZeroMultipleOf
上述相同的操作。(至少通过使用>>
它对用户来说更明显的是发生了一些奇怪的事情而不是重载%
运算符):
public struct MyInteger
{
private readonly Int32 value;
public MyInteger( Int32 value )
{
this.value = value;
}
public static implicit operator Int32( MyInteger mi ) => mi.value;
public static implicit operator MyInteger( Int32 value ) => new MyInteger( value );
public static Boolean operator >>(MyInteger value, Int32 divisor)
{
return ( value.value > 0 ) && ( value.value % divisor ) == 0;
}
}
用法:
// Note that `Settings.Trk3` is still an `Int32`. The assignment to `MyInteger` works because of the `implicit operator` feature.
MyInteger mi = Settings.Trk3;
if( mi >> 20 )
{
// Do something.
}
因为此代码使用值类型的结构,仅进行非虚拟调用并且没有堆分配(new
用于 C# 中结构的堆栈分配,而不仅仅是 GC 堆)此代码也应该很好用在零影响的性能关键代码中。
推荐阅读
- docker - 需要在 ubuntu “docker-compose up -d” 中升级我的 docker 文件
- apache - 除了主目录之外,是否可以在 Ubuntu 上更改 Apache Web 根目录?
- javascript - 在 chrome 扩展中运行 Python?
- c++ - clang-cl 错误:lld-link:错误:未定义符号:__divti3
- python - django中HTML条件渲染的好习惯?
- reactjs - 在 React 中使用 Sanctum 的密钥
- javascript - 我可以使用 JOI 跨不同对象使用验证唯一键吗?
- groovy - Groovy 附加“。” 插值变量时
- spring-boot - 为什么 SonarQube 在使用 @SuperBuilder 时会说“可能通过合并对可变对象的引用来暴露内部表示”。?
- desire2learn - brightspace/d2l 是否有获取所有 CanSelfRegister 课程的 API