从架构上来说,我应该怎么替换的东西更容易管理的一个非常大的switch语句? [英] Architecturally speaking, how should I replace an extremely large switch statement with something more manageable?

查看:165
本文介绍了从架构上来说,我应该怎么替换的东西更容易管理的一个非常大的switch语句?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

修改1:忘记添加嵌套属性弧线球

EDIT 1: Forgot to add the nested property curve ball.

更新:我选择了@ mtazva的答案,那是我的特殊情况下,preferred解决方案。现在回想起来,我问了一个普遍的问题有一个很具体的例子,我相信,结束了混乱的每个人(或者只是我),至于问题是究竟是什么。我相信一般的问题已经回答以及(见的策略模式解答和链接)。谢谢大家!

UPDATE: I have chosen @mtazva's answer as that was the preferred solution for my specific case. In retrospect, I asked a general question with a very specific example and I believe that ended up confusing everyone (or maybe just me) as to what the question was exactly. I do believe the general question has been answered as well (see the Strategy pattern answers and links). Thanks everyone!

大的switch语句显然,然后我看到的怎么样,你可以用做一些链接一个字典映射到功能的。但我不知道是否有更好(或更聪明的方法)来做到这一点?在某种程度上,这是一个问题的排序总是我已经在我的后脑勺滚来滚去,但从来没有真正很好地解决了。

Large switch statements obviously smell and I have seen some links on how you could do this with a dictionary that maps to functions. But I'm wondering if there is a better (or smarter way) to do this? In a way, this is a question I've always sort of had rolling around in the back of my head but never really had a good solution to.

此问题,从另一个问题,我刚才问朵朵:<一href="http://stackoverflow.com/questions/7396315/how-to-select-all-the-values-of-an-objects-property-on-a-list-of-typed-objects-i">How选择在.net类型的对象用C#

This question stemmed from another question I asked earlier: How to select all the values of an object's property on a list of typed objects in .Net with C#

下面是一个例子类,我有工作(从外部源):

Here is an example class I'm working with (from an external source):

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
}

不幸的是,这是从外部来了...从侠盗什么想象一个巨大的数据转储。

Unfortunately, this is coming from an external source... imagine a HUGE data dump from Grand Theft Auto or something.

和我想要得到这些对象的列表只是一个小的横截面。试想一下,我们希望能够为您和一帮朋友的游戏信息的对象进行比较。单个结果为一个用户是这样的:

And I want to get just a small cross section of a list of these objects. Imagine we want to be able to compare you with a bunch of your friends' game info objects. An individual result for one user would look like this:

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语句):

And an example of what I want to replace with something more manageable (believe me, I DON'T want to be maintaining this monster switch statement):

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;
}

所以,问题是是否有任何合理的方式来管理这头野兽?我真正喜欢的是一个动态的方式来获得的情况下,这个信息是初始对象的改变(更多的游戏信息属性的添加,例如)。有没有更好的方式来架构这个所以它不太笨拙?

So the question is are there any reasonable ways to manage this beast? What I'd really like is a dynamic way to get this info in case that initial object changes (more game info properties are added, for instance). Is there a better way to architect this so it's less clumsy?

推荐答案

我想你的第一句话躲避什么可能是最合理的解决方案:某种形式的字典映射值的方法。

I think your first sentence eluded to what is probably the most reasonable solution: some form of dictionary mapping values to methods.

例如,你可以定义一个静态词典&LT; INT,FUNC&LT;的GameInfo,串&GT;&GT; ,其中每个值,如MATCHES_WON将与相应的lambda添加提取适当的值(假设你的常数,等被定义为显示在您的例子):

For example, you could define a static Dictionary<int, func<GameInfo, string>>, where each value such as MATCHES_WON would be added with a corresponding lambda that extracts the appropriate value (assuming your constants, etc are defined as shown in your example):

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
    };

您可以使用这个字典来提取值的样本方法:

You can then use this dictionary to extract the value in your sample method:

public static List<MyResult> GetMyResult(GameInfo[] gameInfos, int input)
{
  return gameInfo.Select(gi => new MyResult()
         {
            UserId = gi.UserId, 
            ResultValue = valueExtractors[input](gi)
         }).ToList<MyResult>();
}

这个选项之外,你可能有某种形式的文件/数据库/存储查询的数量和属性名的,然后使用反射来提取价值,但显然不会执行,以及。

Outside of this option, you could potentially have some sort of file/database/stored lookup with the number and the property name, then use reflection to extract the value, but that would obviously not perform as well.

这篇关于从架构上来说,我应该怎么替换的东西更容易管理的一个非常大的switch语句?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆