查找每个字典以检查派生类

本文关键字:检查 派生 字典 查找 | 更新日期: 2023-09-27 18:12:22

我有一个基类 Rules.cs。有两个衍生类RowRules.csColumnRules.cs。我还有一节Test.cs课。这个类有一个持续添加值的Dictionary <int, Rules>。当我循环遍历字典时,我需要知道该值是RowRule还是ColumnRule。为了更好地理解,我有下面的代码。

Rules.cs

class Rules
{
    private int m_timepointId = 0;
    private int m_studyId = 0;
    public int TimepointId
    {
        get { return m_timepointId; }
        set { m_timepointId = value;}
    }
    public int StudyId
    {    
        get { return m_studyId; }
        set {m_studyId = value; }
    }
}

RowRules.cs

class RowRules : Rules
{
   private int m_row;
   public int Row
   {
       get { return m_row; }
       set { m_row = value; }
   }
}

ColumnRules.cs

class ColumnRules: Rules
{
    private int m_column;
    public int Column
    {
        get { return m_column; }
        set { m_column = value; }
    }
}

main class 我有

private Dictionary<int, Rules> m_testDictionary = new Dictionary<int, Rules>();
ColumnRules columnrules = new ColumnRules();
RowRules rowRules = new RowRules();
rowRules.Row = 1;
rowRules.StudyId = 1;
m_testDictionary.Add(1, rowRules);
columnRules.Column = 2;
columnRules.TimepointId = 2;
m_testDictionary.Add(2, columnRules);
foreach(.... in m_testDictionary)
{
     //Need code here.
    //if(... ==  RowRules)
      {
      }
}

现在,我需要知道foreach循环中的值是多少。此外,我需要知道特定的字典行是RowRule还是ColumnRule。希望我把问题讲清楚了。任何帮助都会非常感激。

查找每个字典以检查派生类

有一堆答案告诉你使用"is"来测试类型。这很好,但在我看来,如果你关闭对象的类型,你可能做错了什么。

通常,当您需要从基类获得额外的和不同的功能时,使用派生类。此外,通过virtualabstract方法实现的特殊多态性意味着您可以让运行时找出类型,从而显著地使代码更加简洁。

例如,在您的案例中,您可能希望使用abstract ApplyRule()方法使Rules成为abstract类。然后,每个子类都可以实现该方法,并充分了解该类型规则的含义:

public class Rules
{
    private int m_timepointId = 0;
    private int m_studyId = 0;
    public int TimepointId
    {
        get { return m_timepointId; }
        set { m_timepointId = value;}
    }
    public int StudyId
    {    
        get { return m_studyId; }
        set {m_studyId = value; }
    }
    // New method
    public abstract void ApplyRule();
}
class RowRules : Rules
{
   private int m_row;
   public int Row
   {
       get { return m_row; }
       set { m_row = value; }
   }
   public override void ApplyRule() { // Row specific implementation }
}
class ColumnRules : Rules
{
    private int m_column;
    public int Column
    {
        get { return m_column; }
        set { m_column = value; }
    }
   public override void ApplyRule() { // Column specific implementation }
}
现在,你的循环就是:
foreach(var kvp in m_testDictionary)
{
    kvp.Value.ApplyRule();
}

应该可以:

foreach(KeyValuePair<int, Rules> pair in m_testDictionary)
{
    if(pair.Value is RowRule)
    {
         // do row rule stuff
    }
    if(pair.Value is ColumnRule)
    {
         // do row column rule stuff
    }
}

关于is关键字的更多信息

试试下面的

foreach(var rule in in m_testDictionary.Values)
{
  var rowRules = rule as RowRules;
  if (rowRules != null) {
    // It's a RowRules
    continue;
  }
  var columnRules = rule as ColumnRules;
  if (columnRules != null) {
    // It's a ColumnRules
    continue;
  }
}

你可以试试:

foreach(var key in m_testDictionary.Keys)
{
   var value = m_testDictionary[key];
   if(value is RowRules)
   {
      //test your code.....
   }
}

代码工作吗?我相信你添加了两次相同的键。我相信这是你想要的代码:

foreach(int key in m_testDictionary.Keys)
{
    RowRules row = m_testDictionary[key] as RowRules;
    if(row !=null)
      {
            //code here:)
      }
}