Vinay
Vinay

Reputation: 1064

foreach dictionary to check derived class

I have a base class Rules.cs. There are 2 derived classes RowRules.cs and ColumnRules.cs. I have another class Test.cs. This class has a Dictionary <int, Rules> which keeps adding the values. When I loop through the dictionary I need to know if the value is a RowRule or a ColumnRule. To better understand I have the code below.

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; }
    }
}

In the main class I have

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)
      {

      }
}

Now, I need to know what value will go in the foreach loop. Also, I need to know whether that particular dictionary row is a RowRule or a ColumnRule. Hope I am clear with the question. Any help will be really appreciated.

Upvotes: 0

Views: 557

Answers (5)

Jetti
Jetti

Reputation: 2458

This should work:

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
    }
}

Here is more information on the is keyword.

Upvotes: 4

Ross Dargan
Ross Dargan

Reputation: 6021

does that code work? You have added the same key twice I believe. This is the code you wanted I believe:

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

            //code here:)
      }
}

Upvotes: 0

dlev
dlev

Reputation: 48596

There are a bunch of answers that are telling you to test the type using "is". That's fine, but in my opinion if you're switching off the type of an object, you're probably doing something wrong.

Typically, derived classes are used when you need additional and varied functionality from a base class. Moreover, ad-hoc polymorphism via virtual and abstract methods means that you can let the run-time figure out the type, leading to significantly cleaner code.

For example, in your case, you might want to make Rules an abstract class, with an abstract ApplyRule() method. Then, each subclass can implement the method, with the full knowledge of what it means to be a rule of that type:

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 }
}

Now, your loop is just:

foreach(var kvp in m_testDictionary)
{
    kvp.Value.ApplyRule();
}

Upvotes: 5

yiyang
yiyang

Reputation: 41

You can try this:

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

Upvotes: 1

JaredPar
JaredPar

Reputation: 754745

Try the following

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;
  }
}

Upvotes: 2

Related Questions