微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何实现仅选择特定类型项目的功能? 上下文代码问题代码

如何解决如何实现仅选择特定类型项目的功能? 上下文代码问题代码

上下文

我有一个 Question 类。它有三个子类:

  • ChoiceQuestion
  • ShortTextQuestion
  • LongTextQuestion

我有一个 Repository 类,它有一个 IEnumerable<Question>


代码

问题类层次结构和容器类 Repository

class Question {}
class ChoiceQuestion : Question {}

class ShortTextQuestion : Question {}

class LongTextQuestion : Question {}

class Repository
{
    IEnumerable<Question> Questions { get; set; }
}

问题

我想从这些存储库中为 Questionnaire 挑选几个问题。

我有一个 IQuestionnaireBuilder,它有一个 AddSource() 方法,可以帮助配置从哪个存储库中挑选问题以及如何挑选问题。我有包含此配置的 QuestionnaireSource 类。

目前,我可以指定从哪个存储库中选择,每个难度选择多少问题。我想指定它应该只选择特定子类型的问题。

例如,要选择的问题必须是 ChoiceQuestionShortTextQuestion。我遇到过 System.Type,但我想限制类型,以便它们必须从 Question 派生。


代码

IQuestionnaireBuilder

interface IQuestionnaireBuilder
{
    IQuestionnaireBuilder AddSource(Action<QuestionnaireSource> source);
}

问卷来源

class QuestionnaireSource
{
    public Repository Repository { get; set; }

    public IDictionary<QuestionDifficulty,int> { get; set; }
    
    // <Property/method to configure which subclasses to include,they must derive from Question>
}

问题难度

enum QuestionDifficulty
{ Easy,Medium,Hard }
    IQuestionnaireBuilder builder = new QuestionnaireBuilder();
    
    Repository repo1 = someExternalProvider.GetRepo(1);
    Repository repo2 = someExternalProvider.GetRepo(2);
    builder
        .AddSource(source => {
            source.Repository = repo1;
            source.Count[QuestionDifficulty.Easy] = 10;
            source.Count[QuestionDifficulty.Medium] = 7;
            source.Count[QuestionDifficulty.Hard] =  3;
            source.PickOnlySpecificSubclassesOfQuestion() // how to implement this? 
       })
       .AddSource(source => {
            source.Repository = repo2;
            source.Count[QuestionDifficulty.Easy] = 30;
            source.Count[QuestionDifficulty.Medium] = 15;
            source.Count[QuestionDifficulty.Hard] =  5;
            source.PickOnlySpecificSubclassesOfQuestion() // how to implement this? 
       })    

在上面的代码段中,我如何实现 PickOnlySpecificSubclassesOfQuestion() 部分?

解决方法

一种方法是使您的 PickOnlySpecificSubclassesOfQuestion 泛型化,并向它传递一个表示您想要的问题类型的参数。

public void PickOnlySpecificSubclassesOfQuestion<T>()
where T : Question

在该方法中,您可以获得一个 System.Type,代表所请求的问题类型,如下所示:

Type desiredTypeOfQuestion = typeof(T);

然后,给定包含所有不同类型问题的 IEnumerable 个问题,您可以使用 Linq 和 Reflection 查找可从所需类型分配的问题:

return myQuestions.Where(q => q.GetType().IsAssignableFrom(desiredTypeOfQuestion));

我相信还有其他方法也行得通,但这是最容易想到的方法。

,

这就是我使用委托完成的方式。我向 Filter 类型的 QuestionnaireSource 添加了一个 System.Predicate<T> 属性。 System.Predicate<T> 是一个定义如下的委托:

public delegate bool Predicate<in T>(T obj);

您也可以使用 Func<Question,bool> 或您自己的委托类型。

在我的 QuestionnaireSource 类中,我添加了 Filter 属性:

class QuestionnaireSource
{
    public Repository Repository { get; set; }

    public IDictionary<QuestionDifficulty,int> { get; set; }
    
    public Predicate<Question> Filter { get; set; }
}

现在我可以传递如下的 lambda 表达式:

question => question is ChoiceQuestion

现在我可以更灵活地过滤,这要归功于 C# 与 is 的模式匹配。 我可以在构建问卷时使用 AddSource()QuestionnaireBuilder 方法将其配置如下:

builder
    .AddSource(source => {
        source.Repository = repo1;

        source.Count[QuestionDifficulty.Easy] = 10;
        source.Count[QuestionDifficulty.Medium] = 7;
        source.Count[QuestionDifficulty.Hard] =  3;

        source.Filter = question => question is ChoiceQuestion  
    });

现在我可以过滤或包含多种类型:

question => question is ChoiceQuestion || question is ShortTextQuestion

不仅如此,我还可以使用其他条件进行过滤,例如问题文本:

question => question.Text.Trim().StartsWith("What");

如果您只想选择一种子类型,@benjamin 的答案也适用,但如果要选择或忽略多种类型,这种过滤方法似乎更灵活。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?