如何使接受输入的方法成为类对象的属性?

How to make a method, that accepts an input, into a property of a class object?

提问人:kenLeeDep 提问时间:8/1/2023 更新时间:8/1/2023 访问量:81

问:

我在这里遇到的问题是,我目前正在尝试制作一个将方法作为属性的对象。我能够让它在公共静态 void 方法上工作,但不能返回我想要的东西的方法。

为了解释我想要做什么,我正在尝试编写一个小型多项选择游戏,该游戏可以随机化问题和您拥有的选择。它有一个具有身高、体重和分数等属性的学生列表,以及会问谁最高或谁得分最低等问题的问题。

我确实设法编写了一个有效的方法并设法重构了很多,但我想改进我的代码,所以我决定尝试将方法制作成一个属性。(我的原来有很多 IF,并使用唯一的 ID 号来确定如何对选项列表进行排序)

以下是主要代码:

static void Main(string[] args)
        {     

            Shuffler shuffler = new Shuffler();
            shuffler.Shuffle(QuestionList.listQuestions);

            Question tester = QuestionList.listQuestions[0];

            Console.WriteLine(tester.text);
            tester2.method();

            Console.ReadLine();
        }
    }

所以我想做的是,抓住我在另一个班级中创建的问题列表,随机播放,然后让它执行第一个问题。

下面的代码是我让它工作的代码:

public class Question
    {
        public string text { get; set; }
        public Action method { get; set; }

        public Question()
        {

        }

        public Question(string textInput, Action methodInput)
        {
            text = textInput;
            method = methodInput;
        }
    }

    public class QuestionList
    {
        public static List<Question> listQuestions = new List<Question>();

        static QuestionList()
        {
            PopulateQuestionList();
        }

        private static void PopulateQuestionList()
        {
            listQuestions.Add(new Question("Who has the latest birthday?", Question1));
            listQuestions.Add(new Question("Who has the earliest birthday?", Question2));
            listQuestions.Add(new Question("Who is the tallest?", Question3));
            listQuestions.Add(new Question("Who is the shortest", Question4));
        }

        public static void Question1()
        {
            Console.WriteLine("Question 1");
        }

        public static void Question2()
        {
            Console.WriteLine("Question 2");
        }

        public static void Question3()
        {
            Console.WriteLine("Question 3");
        }

        public static void Question4()
        {
            Console.WriteLine("Question 4");
        }

因此,当我运行代码时,它会给我“谁的生日最晚?”和“问题 1”。然而,这就是我被卡住的地方。以下是我将其更改为的方法:

public static List<Student> Question1(List<Student> testing)
{
    testing.Sort((x, y) => y.birthday - x.birthday);
    return testing;
}

代码本身,至少当我尝试在我的工作测验中使用它时,是有效的。(我取 4 个选项的列表,按降序随机化,如果用户答案与第一个匹配,则正确。但是,在本例中,它有一个错误,指出 Question 构造函数不满足。

我试图做的是,看看一个更简单的方法是否有效,一个不需要我使用如下自定义类的方法,它仍然返回相同的问题。

        public static string Question1(string test)
        {
            test = "determine";
            return test;
        }

当我在网上搜索时,我读到这是因为 Action 变量委托给一个没有任何参数的函数,所以这就是为什么 void 方法有效但不需要返回某些东西的原因。因此,我当时的想法当然是,可能有一个允许参数输入的变量。然而,我的方法似乎是错误的。

所以我想问,我能做些什么吗?我对编码很陌生,因为只有一个月的时间,我在网上找到的一些解决方案是我什至不知道如何处理的概念和帖子。

感谢您的阅读。如果需要进一步的澄清或细节,我很乐意提供。

C# 对象 方法 属性

评论

0赞 Etienne de Martel 8/1/2023
是的,没有争论。有采用单个参数的方法。ActionAction<T>
0赞 Wh1t3rabbit 8/1/2023
如果你想退货,那里有Func<T,TResult>
0赞 kenLeeDep 8/1/2023
Func<T,TResult>起作用了。谢谢。但是,我想知道,到目前为止,我的问题是相当简单的比较,但是如果有必要,是否有接受多个论点的变量?我还想补充一点,这些听起来像是非常基本的修复,但它们很容易让我躲避。我当时观看的视频课程和我正在做的事情感觉就像将手指浸在表面上。有什么好的改进方法吗?
0赞 John Alexiou 8/1/2023
我认为在这种情况下使用属性会导致糟糕的设计。这是 oop 而不是作者的一般缺点。使用字典来保存数据以用于测验将导致更直接的设计,而不是使用类。Student
0赞 kenLeeDep 8/2/2023
我会查字典,谢谢。

答:

0赞 JonasH 8/1/2023 #1

如果希望委托接受一个参数,可以使用 ,并且有接受多个参数的变体,依此类推。如果还想返回一个值,可以使用 ,其中最后一个泛型类型参数始终是返回类型。此外,对于需要更多参数的变体,因此签名应该用于您的列表示例。但你也可以声明你自己的:Action<T>Action<T1, T2>Func<T1, TResult>Func<List<Student>, List<Student>>

public delegate List<Student> MyQuestionDelegate(List<Student> testing);

如果泛型变体变得很长,这可能会提高可读性,但根据我的经验,Action/Func 在今天更常见,因此新开发人员可能不熟悉自定义委托。

但一个更令人担忧的问题是你打算用什么 API 来回答你的问题。如果您的问题方法签名是,您将限制自己与学生有关的问题。也许这很好?我不知道你的问题域。但是对于像多项选择题这样的东西,我本来希望有更抽象的东西,比如:List<Student> Question(List<Student> testing)

public interface IQuestion{
    public string Question {get;}
    public IReadOnlyList<string> Choices {get;}
    public int CorrectChoiceIndex {get;}
}

评论

0赞 kenLeeDep 8/2/2023
谢谢你的回答。它帮助我解决了很多问题。谢谢。