Is there any other way to do this without all the extra outside parens here?
((ScheduledTask)(scheduledTasks[intCount])).TaskIntervalType
3 Answers 3
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.
-
9\$\begingroup\$ Not equivalent statement. \$\endgroup\$Alex Aza– Alex Aza2011年06月25日 03:55:01 +00:00Commented Jun 25, 2011 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 usingas
keyword \$\endgroup\$Jalal Said– Jalal Said2011年06月25日 03:57:45 +00:00Commented Jun 25, 2011 at 3:57 -
3\$\begingroup\$ Indeed, not equivalent. Not only does it throw a
NullReferenceException
instead of anInvalidCastException
(thus making it harder to debug what went wrong), theas
operator also doesn't use custom conversions defined by classes which the original does. \$\endgroup\$Sven– Sven2011年06月25日 03:59:49 +00:00Commented Jun 25, 2011 at 3:59 -
1\$\begingroup\$ @Sven It does not throw
NullReferenceException
. It simply returnsnull
. \$\endgroup\$2011年06月25日 04:03:23 +00:00Commented Jun 25, 2011 at 4:03 -
2\$\begingroup\$ The
as
operator itself doesn't throw aNullReferenceException
, but his code does because it tries to use the result without checking fornull
. \$\endgroup\$Sven– Sven2011年06月25日 04:25:14 +00:00Commented Jun 25, 2011 at 4:25
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;
}
-
\$\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– CoffeeAddict2011年07月10日 04:20:15 +00:00Commented Jul 10, 2011 at 4:20
-
2\$\begingroup\$ @CoffeeAddict Nothing I wrote requires you to use
var
. Feel free to replace it with explicit types. :) \$\endgroup\$2011年07月10日 04:35:54 +00:00Commented Jul 10, 2011 at 4:35
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;
}
scheduledTasks[intCount]
but that's as far as you can go without changing toas
casting or using local variables... \$\endgroup\$