如何避免 300 个 case 的 switch 阻塞?

发布于 2024-12-07 17:04:44 字数 3019 浏览 0 评论 0原文

我正在尝试将 300 个挑战添加到我的程序中,但仅在 CompletionValue.IsChecked = false; 时才显示它们;

如果你正在创建这个程序。您将如何存储挑战? 我正在使用交换机,但 300 个案例有点过分了,有更好的方法吗?

任何有关改进代码的建议都将受到高度赞赏。 我对此有点陌生。

    Random rand = new Random();
    // Constructor
    public MainPage()
    {
        InitializeComponent();
        AnswerValue.Visibility = Visibility.Collapsed;
        Load();

    }


    private void Load()
    {
        int random = rand.Next(1, 4);
        switch (random)
        {
            case 1:
                Challenge1();
                break;
            case 2:
                Challenge2();
                break;
            case 3:
                Challenge3();
                break;
        }
    }

    private void Challenge1()
    {
        DifficultyValue.Text = "20%";
        CompletionValue.IsChecked = false;
        TitleValue.Text = "Chicken or Egg?";
        QuestionValue.Text = "Can you answer the ancient question: Which came first the chicken of the egg?";
        bmp.UriSource = new Uri("Images/Challenge1.png", UriKind.Relative);
        ImageValue.Source = bmp;
        ImageValue.Visibility = Visibility.Visible;
        ResourceValue.Text = "Resource: Brain Games";
        AnswerValue.Text = "The Egg. According to paleontologists, reptiles and dinosaurs existed long before birds and chickens.  Fossilized eggs dating back on hundred millions years have been uncovered. Thus it can be said that eggs came before chickens.";

    }

    private void Challenge2()
    {
        DifficultyValue.Text = "25%";
        CompletionValue.IsChecked = false;
        TitleValue.Text = "Halving Seven";
        QuestionValue.Text = "Can you prove that seven is half of twelve?";
        bmp.UriSource = new Uri("Images/Challenge2.png", UriKind.Relative);
        ImageValue.Source = bmp;
        ImageValue.Visibility = Visibility.Visible;
        ResourceValue.Text = "Resource: Yahoo Questions";
        AnswerValue.Text = "Roman numeral for 12 - XII \n Cut the roman numeral in half. you will get VII, which is 7.";

    }

    private void Challenge3()
    {
        DifficultyValue.Text = "25%";
        CompletionValue.IsChecked = false;
        TitleValue.Text = "Three-coin flip";
        QuestionValue.Text = "You ask a friend about probability, and he tells you the following: The odds of three tossed coins turning up all heads or all tails is one in two, that is, fifty-fifty. That’s because anytime you toss three coins, at least two must match, either two heads or two tails.  So that means the third coin—which is equally likely to be heads or tails—determines the odds.” Is your friend right? If not, what are the odds of three tossed coins turning up all heads or all tails?";
        bmp.UriSource = new Uri("Images/Challenge3.png", UriKind.Relative);
        ImageValue.Source = bmp;
        ImageValue.Visibility = Visibility.Visible;
        ResourceValue.Text = "Resource: Brain Games";
        AnswerValue.Text = "Answer will be available soon";
    }

I am trying to add 300 Challenges into my program, but only display them if the CompletionValue.IsChecked = false;

If you were creating this program. How would you store the Challenges?
I am using a switch but having 300 cases is overkill, is there a better way?

Any recommendation on to improve the code is well appreciated.
I am somewhat new to this.

    Random rand = new Random();
    // Constructor
    public MainPage()
    {
        InitializeComponent();
        AnswerValue.Visibility = Visibility.Collapsed;
        Load();

    }


    private void Load()
    {
        int random = rand.Next(1, 4);
        switch (random)
        {
            case 1:
                Challenge1();
                break;
            case 2:
                Challenge2();
                break;
            case 3:
                Challenge3();
                break;
        }
    }

    private void Challenge1()
    {
        DifficultyValue.Text = "20%";
        CompletionValue.IsChecked = false;
        TitleValue.Text = "Chicken or Egg?";
        QuestionValue.Text = "Can you answer the ancient question: Which came first the chicken of the egg?";
        bmp.UriSource = new Uri("Images/Challenge1.png", UriKind.Relative);
        ImageValue.Source = bmp;
        ImageValue.Visibility = Visibility.Visible;
        ResourceValue.Text = "Resource: Brain Games";
        AnswerValue.Text = "The Egg. According to paleontologists, reptiles and dinosaurs existed long before birds and chickens.  Fossilized eggs dating back on hundred millions years have been uncovered. Thus it can be said that eggs came before chickens.";

    }

    private void Challenge2()
    {
        DifficultyValue.Text = "25%";
        CompletionValue.IsChecked = false;
        TitleValue.Text = "Halving Seven";
        QuestionValue.Text = "Can you prove that seven is half of twelve?";
        bmp.UriSource = new Uri("Images/Challenge2.png", UriKind.Relative);
        ImageValue.Source = bmp;
        ImageValue.Visibility = Visibility.Visible;
        ResourceValue.Text = "Resource: Yahoo Questions";
        AnswerValue.Text = "Roman numeral for 12 - XII \n Cut the roman numeral in half. you will get VII, which is 7.";

    }

    private void Challenge3()
    {
        DifficultyValue.Text = "25%";
        CompletionValue.IsChecked = false;
        TitleValue.Text = "Three-coin flip";
        QuestionValue.Text = "You ask a friend about probability, and he tells you the following: The odds of three tossed coins turning up all heads or all tails is one in two, that is, fifty-fifty. That’s because anytime you toss three coins, at least two must match, either two heads or two tails.  So that means the third coin—which is equally likely to be heads or tails—determines the odds.” Is your friend right? If not, what are the odds of three tossed coins turning up all heads or all tails?";
        bmp.UriSource = new Uri("Images/Challenge3.png", UriKind.Relative);
        ImageValue.Source = bmp;
        ImageValue.Visibility = Visibility.Visible;
        ResourceValue.Text = "Resource: Brain Games";
        AnswerValue.Text = "Answer will be available soon";
    }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

小梨窩很甜 2024-12-14 17:04:44

你们面临的挑战看起来非常相似,对吧?在这种情况下,您想要提取通用数据结构,并将每个挑战表示为一段数据。

通过对挑战的统一表示,您可以根据特定挑战 ID 的挑战数据设置 UI。

始终可以将数据移动到 XML 文件、JSON 文件或数据库中,但首先看看简单的 C# 解决方案是否适合您:

// Note: This example is simplified for readability

// Here is the common data structure that can represent all challenges
private class Challenge
{
    public string Title { get; set; }
    public string Question { get; set; }
    public string ImagePath { get; set; }
}

// All of the challenges are defined right here, as simple data
private Challenge[] _allChallenges = new Challenge[]
{
    new Challenge
    {
        Title = "Chicken or Egg?",
        Question = "Can you answer the ancient question: Which came first the chicken of the egg?",
        ImagePath = "Images/Challenge1.png",
    },
    new Challenge
    {
        Title = "Halving Seven?",
        Question = "Can you prove that seven is half of twelve?",
        ImagePath = "Images/Challenge1.png",
    },
}

// Choosing challenges is as simple as indexing into the array
private void Load()
{
    int random = rand.Next(1, 4);
    Challenge chosenChallenge = _allChallenges[random];
    LoadChallenge(chosenChallenge);
}

// Setting up the UI for a challenge means extracting information from the data structure
private void LoadChallenge(Challenge chosenChallenge)
{
    TitleValue.Text = chosenChallenge.Title;
    QuestionValue.Text = chosenChallenge.Text;
    bmp.UriSource = new Uri(chosenChallenge.ImagePath, UriKind.Relative);
    ImageValue.Source = bmp;
    ImageValue.Visibility = Visibility.Visible;
}

您可以将其视为 声明式编程。程序的一个重要部分,即挑战本身,已从命令式语句(设置 UI 属性)转换为非常简单的数据声明。

通过进行此转换,您甚至可以检查每个挑战以确保所有部分均已填写。然后,您将确保为 300 个挑战中的每一个挑战设置标题、问题、资源、答案等。

Your challenges look awfully similar to each other, right? This is a case where you want to extract out a common data structure, and have each challenge represented as a piece of data.

With a uniform representation for your challenges, you set up the UI based on the challenge data for a particular challenge ID.

It is always possible to move your data into XML files, JSON files, or a database, but first see if the simple C# solution works for you:

// Note: This example is simplified for readability

// Here is the common data structure that can represent all challenges
private class Challenge
{
    public string Title { get; set; }
    public string Question { get; set; }
    public string ImagePath { get; set; }
}

// All of the challenges are defined right here, as simple data
private Challenge[] _allChallenges = new Challenge[]
{
    new Challenge
    {
        Title = "Chicken or Egg?",
        Question = "Can you answer the ancient question: Which came first the chicken of the egg?",
        ImagePath = "Images/Challenge1.png",
    },
    new Challenge
    {
        Title = "Halving Seven?",
        Question = "Can you prove that seven is half of twelve?",
        ImagePath = "Images/Challenge1.png",
    },
}

// Choosing challenges is as simple as indexing into the array
private void Load()
{
    int random = rand.Next(1, 4);
    Challenge chosenChallenge = _allChallenges[random];
    LoadChallenge(chosenChallenge);
}

// Setting up the UI for a challenge means extracting information from the data structure
private void LoadChallenge(Challenge chosenChallenge)
{
    TitleValue.Text = chosenChallenge.Title;
    QuestionValue.Text = chosenChallenge.Text;
    bmp.UriSource = new Uri(chosenChallenge.ImagePath, UriKind.Relative);
    ImageValue.Source = bmp;
    ImageValue.Visibility = Visibility.Visible;
}

You can consider this as a form of declarative programming. An important part of your program, the challenges themselves, have been converted from imperative statements (setting UI properties) into very simple data declarations.

By making this conversion, you can even check each challenge to make sure that all of the parts are filled out. Then you'll be sure that the title, question, resource, answer, etc. is set for each of your 300 challenges.

宣告ˉ结束 2024-12-14 17:04:44

您可以将挑战保存在数据库或文件中。我确实看到您使用的是随机数并且仅显示 1 个挑战。 DB 可以是类似的

ChallengeId, DifficultyValue, TitleValue ... 

ChallengeId 将是 QuestionId 编号。因此,根据生成的随机数,您可以选择特定的 ChallengeId 和相关数据。

You can save the challenges in a database or a file. I do see you are using a random number and display only 1 challenge. The DB can be something like

ChallengeId, DifficultyValue, TitleValue ... 

The ChallengeId will be the questionId number. So depending on the random number generated you can choose the particular ChallengeId and the relevant data.

妄司 2024-12-14 17:04:44

您真正应该研究的是封装和多态代码。通过将类似的属性封装到单个类中,您可以更好地表示“挑战”作为一个整体,并能够重用必须一遍又一遍键入的部分(.Text = ". ..") 将使您未来的编码生活无限美好。诚然,即使编写 Challenge 实体列表(如下所示)也并不有趣,您必须在某个时间输入该数据。我们只是将其视为一个编码练习,您可以轻松地调整下面的代码以从数据库或序列化文件填充 _challenges

public class Challenge
{
    public int Id {get;set;}
    public int Difficulty {get;set;}
    public bool IsCompleted {get;set;}
    public string Title {get;set;}
    public string Question {get;set;}
    public string Answer {get;set;}
}

public class MainPage
{
    private List<Challenge> _challenges;
    private Random rand = new Random();
    public MainPage()
    {
        _challenges = new List<Challenge> {
            new Challenge {
                    Id = 1,
                    Difficulty = 20,
                    Title = "What came first?",
                    Question =  "The chicken or the egg?",
                    Answer = "The egg." },
            new Challenge {
                    Id = 2,
                    Difficulty = 30,
                    Title = "Make 7 from 12?",
                    Question =  "Can you prove 7 is half of 12?",
                    Answer = "VII" }};
    }

    public void LoadChallenge(Challenge challenge)
    {
        Difficulty.Test = String.Format("%{0}", callenge.Difficulty);
        Completeted.Value = challenge.IsCompleted;
        Title.Test = challenge.Title;
        // etc
    }

    public void StartNewChallenge()
    {
        Challenge nextChallenge = null;
        while(nextChallenge == null)
        {
            var nextId = rand.Next(1,2);
            nextChallenge = _challenges
                .Where(x => x.Id == nextId && !x.IsCompleted)
                .SingleOrDefault(); // default to null if completed == true
        }
        LoadChallenge(nextChallenge);
    }

}

What you should really look into is encapsulation and polymorphic code. By encapsulating your like properties into a single class, you have a better way of representing the "Challenge" as a whole, and being able to reuse the parts that you have to type over and over again (.Text = "...") will make your future coding life infinitely better. Granted, even coding the list of Challenge entities, as I have below, would be not fun, you have to enter that data somewhere sometime. We're just going to consider this a coding exercise, you could easily adapt the code below to populate _challenges from a database or serialized file.

public class Challenge
{
    public int Id {get;set;}
    public int Difficulty {get;set;}
    public bool IsCompleted {get;set;}
    public string Title {get;set;}
    public string Question {get;set;}
    public string Answer {get;set;}
}

public class MainPage
{
    private List<Challenge> _challenges;
    private Random rand = new Random();
    public MainPage()
    {
        _challenges = new List<Challenge> {
            new Challenge {
                    Id = 1,
                    Difficulty = 20,
                    Title = "What came first?",
                    Question =  "The chicken or the egg?",
                    Answer = "The egg." },
            new Challenge {
                    Id = 2,
                    Difficulty = 30,
                    Title = "Make 7 from 12?",
                    Question =  "Can you prove 7 is half of 12?",
                    Answer = "VII" }};
    }

    public void LoadChallenge(Challenge challenge)
    {
        Difficulty.Test = String.Format("%{0}", callenge.Difficulty);
        Completeted.Value = challenge.IsCompleted;
        Title.Test = challenge.Title;
        // etc
    }

    public void StartNewChallenge()
    {
        Challenge nextChallenge = null;
        while(nextChallenge == null)
        {
            var nextId = rand.Next(1,2);
            nextChallenge = _challenges
                .Where(x => x.Id == nextId && !x.IsCompleted)
                .SingleOrDefault(); // default to null if completed == true
        }
        LoadChallenge(nextChallenge);
    }

}
任性一次 2024-12-14 17:04:44

另一种选择可能是某种工厂方法:

MyForm.cs

public class MyForm
{
    Random rand = new Random();
    // Constructor
    public MainPage()
    {
        InitializeComponent();
        AnswerValue.Visibility = Visibility.Collapsed;
        Load();
    }

    private void Load()
    {
        int random = rand.Next(1, 4);
        DisplayChallenge(ChallengeFactory.GetChallenge(random));
    }

    private void DisplayChallenge(ChallengeFactory.Challenge challengeToDisplay)
    {
        DifficultyValue.Text = String.Format("{0}%", challengeToDisplay.Difficulty);
        CompletionValue.IsChecked = challengeToDisplay.IsChecked;
        TitleValue.Text = challengeToDisplay.Title;
        QuestionValue.Text = challengeToDisplay.Question;
        ImageValue.Source = challengeToDisplay.ImageSource;
        ImageValue.Visibility = challengeToDisplay.Visible;
        ResourceValue.Text = challengeToDisplay.ResourceValue;
        AnswerValue.Text = challengeToDisplay.Answer;
    }
}

ChallengeFactory.cs

public static class ChallengeFactory
{
    public class Challenge
    {
        public int Difficulty { get; set; }
        public bool IsChecked { get; set; }
        public string Title { get; set; }
        public string Question { get; set; }
        public Uri ImageSource { get; set; }
        public bool Visible { get; set; }
        public string ResourceValue { get; set; }
        public string Answer { get; set; }

        private Challenge(int difficulty, bool isChecked, string title, string question, Uri imageSource, bool visible, string resourceValue, string answer)
        {
            // assign each of the arguments to the instance properties
        }
    }

    public static Challenge GetChallenge(int challengeNumber)
    {
        switch(challengeNumber)
        {
            case 1:
                return new Challenge(20, false, "Chicken or Egg?", "Can you answer the ancient question: Which came first the chicken of the egg?", new Uri("Images/Challenge1.png", UriKind.Relative), true, "Resource: Brain Games", "The Egg...");
            break;
            case 2:
                // new challenge for challenge #2
            break;
            case 3:
                // new challenge for challenge #3
            break;
        }
    }
}

请注意,我已将 Challenge 类设置为 Factory 类内部的嵌套类这样做的好处是,您可以将挑战的构造函数设为私有(这意味着您不能通过工厂方法以外的任何方式创建“无效”类型的挑战。坏处这样做的好处是你有通过为其包含的类添加前缀来进一步限定 Challenge 类,即 ChallengeFactory 我认为在这种情况下值得使用额外的限定符

某处如果您计划在代码中定义所有挑战,正如其他人所说,您可以通过在外部数据中定义挑战来显着减少需要编写的代码量(从而减少切换)。来源(例如数据库)并具有读取、解析和创建 Challenge 实例的单一方法。

Yet another alternative might be some kind of factory method:

MyForm.cs

public class MyForm
{
    Random rand = new Random();
    // Constructor
    public MainPage()
    {
        InitializeComponent();
        AnswerValue.Visibility = Visibility.Collapsed;
        Load();
    }

    private void Load()
    {
        int random = rand.Next(1, 4);
        DisplayChallenge(ChallengeFactory.GetChallenge(random));
    }

    private void DisplayChallenge(ChallengeFactory.Challenge challengeToDisplay)
    {
        DifficultyValue.Text = String.Format("{0}%", challengeToDisplay.Difficulty);
        CompletionValue.IsChecked = challengeToDisplay.IsChecked;
        TitleValue.Text = challengeToDisplay.Title;
        QuestionValue.Text = challengeToDisplay.Question;
        ImageValue.Source = challengeToDisplay.ImageSource;
        ImageValue.Visibility = challengeToDisplay.Visible;
        ResourceValue.Text = challengeToDisplay.ResourceValue;
        AnswerValue.Text = challengeToDisplay.Answer;
    }
}

ChallengeFactory.cs

public static class ChallengeFactory
{
    public class Challenge
    {
        public int Difficulty { get; set; }
        public bool IsChecked { get; set; }
        public string Title { get; set; }
        public string Question { get; set; }
        public Uri ImageSource { get; set; }
        public bool Visible { get; set; }
        public string ResourceValue { get; set; }
        public string Answer { get; set; }

        private Challenge(int difficulty, bool isChecked, string title, string question, Uri imageSource, bool visible, string resourceValue, string answer)
        {
            // assign each of the arguments to the instance properties
        }
    }

    public static Challenge GetChallenge(int challengeNumber)
    {
        switch(challengeNumber)
        {
            case 1:
                return new Challenge(20, false, "Chicken or Egg?", "Can you answer the ancient question: Which came first the chicken of the egg?", new Uri("Images/Challenge1.png", UriKind.Relative), true, "Resource: Brain Games", "The Egg...");
            break;
            case 2:
                // new challenge for challenge #2
            break;
            case 3:
                // new challenge for challenge #3
            break;
        }
    }
}

Note that I have made the Challenge class a nested class inside of the Factory class. The good thing about doing this is that you can make the constructor of the challenge private (meaning that you cannot create "invalid" types of challenges through anything but the factory method. The bad thing about doing this is that you have to further qualify the Challenge class by prefixing it with it's containing class, that is, ChallengeFactory. I think it's worth the extra qualifier in this case.

Ultimately I think you are stuck having to create a switch SOMEWHERE if you plan on defining all of your challenges in code. As others have said, you can significantly reduce the amount of code you need to write (and thus, the switch) by defining your challenges in an external data source (such as a database) and having a single method to read, parse, and create a Challenge instance.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文