user2929108
user2929108

Reputation:

How to reference an object of a class in a statement?

At the top of my form I have:

public static int hoursInt;
public static int minutesInt;
public static int secondsInt;
public static int CompletedIn24;

Then further down I have the following to reset the numericUpDown boxes to zero when selecting a new runner:

private void lstRunners_SelectedIndexChanged(object sender, EventArgs e)
{

Runner selectedRunner = (Runner)lstRunners.SelectedItem;

numericUpDown1.Value = 0;
numericUpDown2.Value = 0;
numericUpDown3.Value = 0;
}

Then in the Finish button click event I have:

 hoursInt = Convert.ToInt32(numericUpDown1.Value);
 minutesInt = Convert.ToInt32(numericUpDown2.Value);
 secondsInt = Convert.ToInt32(numericUpDown3.Value);

if (lstRunners.SelectedIndex > -1 && hoursInt + minutesInt + secondsInt != 0)
        {
            // Obtain selected climber
            Runner selectedRunner = (Runner)lstRunners.SelectedItem;
            selectedRunner.Hours = hoursInt;
            selectedRunner.Minutes = minutesInt;
            selectedRunner.Seconds = secondsInt;

            var expertRunner = selectedRunner as Expert;
            if (expertRunner != null)
            {
                expertRunner.UponFinish();
            }

Here is my overriden method in Expert : Runner:

public override void UponFinish()
        {
            base.UponFinish();

            // The integer must increment by one if the time is 24:00:00 or less i.e. 23:59:59 would increment the integer as well
            if (Hours < 24 || (Hours == 24 && Minutes == 0 && Seconds == 0))
            {
                CompletedIn24++;
            }
        }

At present the UponFinish() method in Runner doesn't have anything inside the braces as I'm not sure if anything is required?

I tried to output the CompletedIn24 integer to a string to see if it would work when the button is clicked but the value stayed at zero even if an expert runner was selected and the time was 24:00:00 or less. The integer is not incrementing and I'm not sure what is causing the problem?

Any help would be appreciated.

Upvotes: 0

Views: 84

Answers (7)

King King
King King

Reputation: 63327

Simply use the as keyword like this:

var runner = selectedRunner as Expert;
if(runner != null) runner.UponFinish();

If your class Runner already defines some method called UponFinish, you should define this method as virtual and override that method in the derived classes, like this:

public class Runner {
  public virtual void UponFinish(){
     //...
  }
}
public class Expert : Runner {
  public override void UponFinish(){
    //You talked about the time, I asked for clarification on this
    //but it's still very unclear. I suppose when you mean the time is 24:00:00
    //that means the hours is 24, the minutes is 0 and the seconds is 0
    if(Hours < 24 || (Minutes == 0 && Seconds == 0)) Completedin24++;
  }
}

Then of course you don't need any cast, just call UponFinish and the overridden code (if any) will be called correctly:

selectedRunner.UponFinish(); 

Upvotes: 1

Rik
Rik

Reputation: 29243

if (lstRunners.SelectedItem is Expert)
{
    ((Expert)lstRunners.SelectedItem).UponFinish();
}

Upvotes: 0

R&#233;da Mattar
R&#233;da Mattar

Reputation: 4381

Try this :

if(lstRunners.SelectedItem is Expert)
{
    Expert selectedRunner = lstRunners.SelectedItem as Expert;
    selectedRunner.UponFinish();
}

Upvotes: 0

nvoigt
nvoigt

Reputation: 77304

You can check if your Runner is an ExpertRunner by using the is keyword:

if(selectedRunner is ExpertRunner)

However, in terms of OOP you should never have to do this, you may want to check your hierarchy or logic why you need to handle this case seperately and not in overridden behaviour (function or properties).

Upvotes: 0

Salvatore Sorbello
Salvatore Sorbello

Reputation: 606

There are several ways to do this, exists the operator is for example: Operator IS

Upvotes: 0

David S.
David S.

Reputation: 6105

You can do

if(selectedRunner is Expert)
{
    UponFinish((Expert)selectedRunner);
    //or ((Expert)selectedRunner).UponFinish(); if that was the intention
}

or alternatively

Expert selectedExpert = selectedRunner as Expert;
if(selectedExpert != null)
    UponFinish(selectedExpert);

edit:

If your UponFinish function is already part of both Runner and Expert (that is, overridden in Expert), you don't need to cast selectedRunner before calling it.

Upvotes: 0

Tobberoth
Tobberoth

Reputation: 9527

You can check type like this:

if (selectedRunner.GetType() == typeof(Expert))
{
    Expert expert = (Expert)selectedRunner;
}

Upvotes: 0

Related Questions