需要帮助避免跨多个方法签名的代码重复
我需要将应用程序中的某些数字限制在有效范围内。我创建了代表来处理这个问题。我不知道这是否是正确的方法;我遇到了一些感觉不对劲的事情。
public delegate int RestrictInteger(int minimum, int maximum, int value);
public delegate decimal RestrictDecimal(decimal minumum, decimal maximum, decimal value);
class GameMath
{
public static int RestrictNumber(int minimum, int maximum, int value)
{
if (value < minimum) { value = minimum; }
else if (value > maximum) { value = maximum; }
return value;
}
public static decimal RestrictNumber(decimal minimum, decimal maximum, decimal value)
{
if (value < minimum) { value = minimum; }
else if (value > maximum) { value = maximum; }
return value;
}
}
public class SomeClass
{
public int aValue { get; set; }
public void SetValue(int value)
{
RestrictInteger doRestrict = new RestrictInteger(GameMath.RestrictNumber);
this.aValue = doRestrict(0, 100, value);
}
}
一方面,似乎如果我添加更多签名,那么我希望能够用它们做不同的事情(例如,转换或舍入等)。另一方面,在这两个签名之间,代码是完全相同的。可以吗?或者是否有某种方法可以编写适用于这两种情况的一个操作,即使其他情况可能使用不同的操作?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
是的,您可以使用泛型来做到这一点 - 尽管不能使用
<
和>
。您应该利用这些类型为自己实现IComparable
的事实:(您仍然可以在这里使用原始代码 - 我更喜欢这种条件条件的使用不过,它满足了我不断增长的功能倾向。)
Yes, you can do this with generics - although not with
<
and>
. You should use the fact that these types implementIComparable<T>
for themselves:(You could still use your original code here - I rather like this sort of use of the conditional operator though; it satisfies my growing functional tendencies.)
(我迟到了,但想尝试一下)
我认为这个语法读起来很好:
您可以通过定义一个限制接口来做到这一点:
然后,定义一个提供实现的静态类和一个推断的方法类型:
(I'm late to the party, but wanted to take a shot at it)
I think this syntax reads well:
You can do it by defining a restriction interface:
Then, define a static class which provides the implementation and a method which infers the type:
根据您将如何使用这些数字,在某些情况下,带有隐式运算符的类型可能会很有用。
它允许您使用常见的比较和一元运算符,例如 < <=> >= + -,并混合使用 T 类型和 RestrictedNumber 类型,因此,例如,您可以将 RestrictedNumber 传递给任何需要 double 的方法,同时仍然保留可能具有的初始值已超出范围。
您永远不必调用任何方法来执行限制或转换 - 一切都可以在声明时设置。
使用示例和注释请参阅下面的第二类。
错位了奥卡姆剃刀:
你可以将这种方法与 Bryan 流畅的界面结合起来,并取得很大的进步(尽管你可能并不真正需要这样做,而且这都是疯狂的矫枉过正)。
var n = Restrict>._(25).to_be.greater_than(50);>._(1234.567).to_be.greater_than(0d).and.less_than(50000d)
var p = Restrict
Depending on how you will use these numbers, there may be instances when a type with an implicit operator will be useful.
It allows you to use common comparison and unary operators, such as < <= > >= + -, and to mix usage between the T type and the RestrictedNumber type, so, for example, you can pass a RestrictedNumber to any method that expects a double, all the while still holding on to the initial value that may have been out of range.
You never have to call any methods to perform restriction or casting -- everything can be set upon declaration.
See the second class below for usage examples and notes.
Having misplaced Occam's Razor:
You can combine this approach with Bryan's fluent-ish interface and take this pretty far (though you probably don't really need to and this is all crazy overkill).
var n = Restrict
<int
>._(25).to_be.greater_than(50);var p = Restrict
<double
>._(1234.567).to_be.greater_than(0d).and.less_than(50000d)