- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
编辑 1: 忘记添加嵌套属性曲线球。
更新:我选择了@mtazva 的回答,因为这是针对我的特定案例的首选解决方案。回想起来,我用一个非常具体的例子问了一个一般性问题,我相信这最终让每个人(或者可能只有我)对这个问题到底是什么感到困惑。我相信一般问题也已得到解答(请参阅策略模式答案和链接)。谢谢大家!
明显的大开关语句smell我已经看到一些关于如何使用 dictionary that maps to functions 执行此操作的链接.但我想知道是否有更好(或更聪明的方法)来做到这一点?在某种程度上,这是一个我一直在脑海中盘旋但从未真正找到好的解决方案的问题。
这个问题源于我之前提出的另一个问题:How to select all the values of an object's property on a list of typed objects in .Net with C#
这是我正在使用的示例类(来自外部来源):
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
}
不幸的是,这是来自外部来源...想象一下来自 Grand Theft Auto 或其他东西的巨大数据转储。
我只想获取这些对象列表的一小部分。想象一下,我们希望能够将您与一群 friend 的游戏信息对象进行比较。一个用户的个人结果如下所示:
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;
}
所以问题是有什么合理的方法来管理这只野兽吗?我真正想要的是一种动态方式来获取此信息,以防初始对象发生变化(例如,添加了更多游戏信息属性)。有没有更好的方法来构建它以使其不那么笨拙?
最佳答案
我认为您的第一句话没有说明可能是最合理的解决方案:某种形式的字典映射值到方法。
例如,您可以定义一个静态的 Dictionary<int, func<GameInfo, string>>
,其中每个值(例如 MATCHES_WON)都将添加相应的 lambda 以提取适当的值(假设您的常量等已按照您的示例中所示定义):
private static Dictionary<int, Func<GameInfo, string>> valueExtractors =
new Dictionary<int, Func<GameInfo, string>>() {
{MATCHES_WON, gi => gi.MatchesWon.ToString()},
{BULLETS_FIRED, gi => gi.BulletsFired.ToString()},
//.... etc for all value extractions
};
然后您可以使用这个字典来提取示例方法中的值:
public static List<MyResult> GetMyResult(GameInfo[] gameInfos, int input)
{
return gameInfo.Select(gi => new MyResult()
{
UserId = gi.UserId,
ResultValue = valueExtractors[input](gi)
}).ToList<MyResult>();
}
除此选项外,您可能会使用编号和属性名称进行某种文件/数据库/存储查找,然后使用反射来提取值,但显然效果不佳。
关于c# - 从架构上讲,我应该如何用更易于管理的东西替换一个非常大的 switch 语句?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7396781/
我是一名优秀的程序员,十分优秀!