我今天与一位同事讨论了如何最好地回归两个价值观。 我们有三种不同的意见。问题的重点是,我们不能使用额外的类或结构(因此没有元组),这是这个问题中的首选答案:Clean Code - Are output parameters bad?。
public enum Offset
{
None = 0,
Training = 10,
Cancel = 20
}
static void Main(string[] args)
{
//Option 1
int outValue = 0;
Offset outOffset;
HandleOffset(35, out outValue, out outOffset);
//Option 2
int refValue = 0;
outOffset = SubtractOffset(ref refValue);
//Option 3
outOffset = GetOffsetById(35);
int id = GetIdWithoutOffset(35);
}
//Option 1
public static void HandleOffset(int inValue, out int outValue, out Offset outOffset)
{
outValue = inValue;
outOffset = Offset.None;
if ((inValue-(int)Offset.Cancel)>15)
{
outValue -= (int)Offset.Cancel;
outOffset |= Offset.Cancel;
}
if ((inValue - (int)Offset.Training) > 15)
{
outValue -= (int)Offset.Training;
outOffset |= Offset.Training;
}
}
//Option 2
public static Offset SubtractOffset(ref int id)
{
Offset offset = Offset.None;
if ((id - (int)Offset.Cancel) > 15)
{
id -= (int)Offset.Cancel;
offset |= Offset.Cancel;
}
if ((id - (int)Offset.Training) > 15)
{
id -= (int)Offset.Training;
offset |= Offset.Training;
}
return offset;
}
//Option 3
public static Offset GetOffsetById(int id)
{
Offset offset = Offset.None;
if ((id - (int)Offset.Cancel) > 15)
{
offset |= Offset.Cancel;
}
if ((id - (int)Offset.Training) > 15)
{
offset |= Offset.Training;
}
return offset;
}
//Option 3
public static int GetIdWithoutOffset(int id)
{
if ((id - (int)Offset.Cancel) > 15)
{
id -= (int)Offset.Cancel;
}
if ((id - (int)Offset.Training) > 15)
{
id -= (int)Offset.Training;
}
return id;
}
由于返回值+ ref值,选项2看起来很难看。
由于两个输出参数,选项1似乎也很难看,但事实上它看起来比第二个选项更清晰。
选项3看起来对我来说最干净。
哪些解决方案被认为是最干净的解决方案(如清洁代码中的bob martin一样干净),还是有其他选择来解决问题,我们可能没有想过?
答案 0 :(得分:1)
一般来说,最干净的解决方案是不需要任何out
或ref
- 参数(最好是结构/类,元组也可以)。由于您不允许使用类/结构或元组,这是首选方式,我仍然使用第一个选项来做最简单的方法。
在我看来,第二个选项是完全废话,因为out
- 关键字应该完全符合您的要求,因此使用ref
根本不需要。
第三种选择没问题,虽然非常混乱而且不那么容易。由于您无法使用元组并希望保持清晰的代码,因此请避免使用。
TL; DR:使用第一个选项。
答案 1 :(得分:1)
我只是想把它扔出去,虽然我永远不会在生产中这样做(至少对于公共API)。
另一种选择是使用dynamic返回类型。没有外面的参数。没有参考参考。只对要返回的值进行模糊处理:
public class Program
{
public static void Main()
{
dynamic offset = HandleOffset();
Console.WriteLine(offset);
}
public static dynamic HandleOffset()
{
return new
{
Value = 64,
Offset = Offset.Cancel
};
}
}
public enum Offset
{
None = 0,
Training = 10,
Cancel = 20
}