EDIT 1:忘记添加嵌套属性曲线球。
UPDATE:我选择了 @mtazva 的答案,因为这是我的具体案例的首选解决方案。回想起来,我用一个非常具体的例子提出了一个一般性问题,我相信这最终让每个人(或者也许只是我)对问题到底是什么感到困惑。我确实相信一般问题也已得到解答(请参阅策略模式答案和链接)。感谢大家!
显然大型 switch 语句smell http://c2.com/cgi/wiki?SwitchStatementsSmell我已经看到了一些关于如何使用映射到函数的字典 http://elegantcode.com/2009/01/10/refactoring-a-switch-statement/。但我想知道是否有更好(或更聪明)的方法来做到这一点?在某种程度上,这是一个我一直在脑海中盘旋的问题,但从未真正找到好的解决方案。
这个问题源于我之前问过的另一个问题:如何使用 C# 在 .Net 中的类型化对象列表中选择对象属性的所有值 https://stackoverflow.com/questions/7396315/how-to-select-all-the-values-of-an-objects-property-on-a-list-of-typed-objects-i
这是我正在使用的示例类(来自外部源):
public class NestedGameInfoObject
{
public string NestedName { get; set; }
public int NestedIntValue { get; set; }
public decimal NestedDecimalValue { get; set; }
}
public class GameInfo
{
public int UserId { get; set; }
public int MatchesWon { get; set; }
public long BulletsFired { get; set; }
public string LastLevelVisited { get; set; }
public NestedGameInfoObject SuperCoolNestedGameInfo { get; set; }
// thousands more of these
}
不幸的是,这是来自外部来源......想象一下来自侠盗猎车手之类的巨大数据转储。
我只想获取这些对象列表的一小部分。想象一下,我们希望能够将您与您朋友的一堆游戏信息对象进行比较。一个用户的单独结果如下所示:
public class MyResult
{
public int UserId { get; set; } // user id from above object
public string ResultValue { get; set; } // one of the value fields from above with .ToString() executed on it
}
以及我想用更易于管理的内容替换的示例(相信我,我不想维护这个怪物 switch 语句):
const int MATCHES_WON = 1;
const int BULLETS_FIRED = 2;
const int NESTED_INT = 3;
public static List<MyResult> GetMyResult(GameInfo[] gameInfos, int input)
{
var output = new List<MyResult>();
switch(input)
{
case MATCHES_WON:
output = gameInfos.Select(x => new MyResult()
{
UserId = x.UserId,
ResultValue = x.MatchesWon.ToString()
}).ToList<MyResult>();
break;
case BULLETS_FIRED:
output = gameInfos.Select(x => new MyResult()
{
UserId = x.UserId,
ResultValue = x.BulletsFired.ToString()
}).ToList<MyResult>();
break;
case NESTED_INT:
output = gameInfos.Select(x => new MyResult()
{
UserId = x.UserId,
ResultValue = x.SuperCoolNestedGameInfo.NestedIntValue.ToString()
}).ToList<MyResult>();
break;
// ad nauseum
}
return output;
}
那么问题来了,有没有什么合理的方法来管理这个野兽呢?我真正想要的是一种动态方式来获取此信息,以防初始对象发生更改(例如添加更多游戏信息属性)。有没有更好的方法来构建它,使其不那么笨拙?