gpt4 book ai didi

c# - 从架构上讲,我应该如何用更易于管理的东西替换一个非常大的 switch 语句?

转载 作者:太空狗 更新时间:2023-10-29 20:49:33 24 4
gpt4 key购买 nike

编辑 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/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com