foreach словарь для проверки производного класса - PullRequest
0 голосов
/ 26 октября 2011

У меня есть базовый класс Rules.cs.Есть 2 производных класса RowRules.cs и ColumnRules.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.Надеюсь, у меня с вопросом все в порядке.Любая помощь будет по достоинству оценена.

Ответы [ 5 ]

5 голосов
/ 26 октября 2011

Есть куча ответов, которые говорят вам проверить тип, используя «is».Это нормально, но, по моему мнению, если вы отключаете тип объекта, вы, вероятно, делаете что-то не так.

Как правило, производные классы используются, когда вам требуется дополнительная и разнообразная функциональность из базового класса.,Кроме того, специальный полиморфизм с помощью методов virtual и abstract означает, что вы можете позволить run-time определить тип, что приведет к значительно более чистому коду.

Например,в вашем случае вы можете захотеть сделать Rules класс abstract с методом abstract ApplyRule().Затем каждый подкласс может реализовать метод с полным знанием того, что значит быть правилом этого типа:

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();
}
4 голосов
/ 26 октября 2011

Это должно работать:

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 .

2 голосов
/ 26 октября 2011

Попробуйте следующее

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;
  }
}
1 голос
/ 26 октября 2011

Вы можете попробовать это:

foreach(var key in m_testDictionary.Keys)
{
   var value = m_testDictionary[key];
   if(value is RowRules)
   {
      //test your code.....
   }
}
0 голосов
/ 26 октября 2011

этот код работает? Вы добавили один и тот же ключ дважды, я верю. Это код, который вы хотели, я верю:

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

            //code here:)
      }
}
...