1
\$\begingroup\$

Is there any other way to do this without all the extra outside parens here?

((ScheduledTask)(scheduledTasks[intCount])).TaskIntervalType
\$\endgroup\$
  • 4
    \$\begingroup\$ You can drop the parentheses surrounding scheduledTasks[intCount] but that's as far as you can go without changing to as casting or using local variables... \$\endgroup\$ – BoltClock Jun 25 '11 at 3:53
5
\$\begingroup\$

Somewhat better:

(scheduledTasks[intCount] as ScheduledTask).TaskIntervalType

Note that the behavior would be somewhat different: The as cast will not throw an exception when not successful, but return null - so you would get a NullReferenceException (when trying to access the property on a null reference) instead of a cast exception.

\$\endgroup\$
  • 9
    \$\begingroup\$ Not equivalent statement. \$\endgroup\$ – Alex Aza Jun 25 '11 at 3:55
  • \$\begingroup\$ If you are sure that that the value is ScheduledTask and that it is not null then using ((ScheduledTask)(scheduledTasks[intCount])) is better form performance than using as keyword \$\endgroup\$ – Jalal Said Jun 25 '11 at 3:57
  • 3
    \$\begingroup\$ Indeed, not equivalent. Not only does it throw a NullReferenceException instead of an InvalidCastException (thus making it harder to debug what went wrong), the as operator also doesn't use custom conversions defined by classes which the original does. \$\endgroup\$ – Sven Jun 25 '11 at 3:59
  • 1
    \$\begingroup\$ @Sven It does not throw NullReferenceException. It simply returns null. \$\endgroup\$ – Adam Lear Jun 25 '11 at 4:03
  • 2
    \$\begingroup\$ The as operator itself doesn't throw a NullReferenceException, but his code does because it tries to use the result without checking for null. \$\endgroup\$ – Sven Jun 25 '11 at 4:25
4
\$\begingroup\$
var task = (ScheduledTask)scheduledTasks[intCount];
var interval = task.TaskIntervalType;

You could use the as keyword instead:

var task = scheduledTasks[intCount] as ScheduledTask;
var interval = task.TaskIntervalType;

but it would change the behaviour of the cast. For one, as noted, it will return null instead of throwing an exception for a failed conversion. For another, it will not perform any custom conversions between types that you might have.

Although with that said, using as is probably better than casting because it behaves in a more consistent and reliable way than a cast.

And with all that said, perhaps the right approach would be to change your array to be strongly typed or expose the TaskIntervalType as a property on an interface or base class? That way casting would not be needed at all.

For example,

public interface ITask
{
    IntervalType TaskIntervalType { get; }
}

public ScheduledTask : ITask
{}

public MyStuff()
{
    List<ITask> scheduledTasks = new List<ITask>();
    // populate the list, etc...

    /// ... and back to your example:
    var type = scheduledTasks[intCount].TaskIntervalType;
}
\$\endgroup\$
  • \$\begingroup\$ If I was a var advocate this would rock. Unfortunately my preference is that I don't like the var keyword. I don't want to get into that debate either but thanks for your post...this is a useful reply to people who are var advocates or willing to embrace var :). \$\endgroup\$ – CoffeeAddict Jul 10 '11 at 4:20
  • 2
    \$\begingroup\$ @CoffeeAddict Nothing I wrote requires you to use var. Feel free to replace it with explicit types. :) \$\endgroup\$ – Adam Lear Jul 10 '11 at 4:35
0
\$\begingroup\$

It could be safer (not sure about the variable names and types):

    ScheduledTask Task =  scheduledTasks[intCount] as ScheduledTask;

    IntervalType TaskType;

    if (Task != null)
    {
        TaskType = Task.TaskIntervalType;
    }
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy