Reputation: 60361
I'm looking at a function with this pattern:
if( obj is SpecificClass1 )
{
((SpecificClass1)obj).SomeMethod1();
}
else if( obj is SpecificClass2 )
{
((SpecificClass2)obj).SomeMethod2();
}
else if( obj is SpecificClass3 )
{
((SpecificClass3)obj).SomeMethod3();
}
and get a Code Performance Analysis Warning: CA1800 Do not cast unnecessarily.
Why do the double casts (using the 'is' operator in the if expression and the parenthesis style cast in the body of each if) not get optimized away by the compiler. I can't see why this would be a performance problem the compiler can't solve.
Upvotes: 2
Views: 201
Reputation: 612864
Simply put, the compiler would prefer you to change:
if( obj is SpecificClass1 )
{
((SpecificClass1)obj).SomeMethod1();
}
to
SpecificClass1 Class1Obj = obj as SpecificClass1;
if (Class1Obj != null)
{
Class1Obj.SomeMethod1();
}
Yes, it is conceivable that the compiler could do the transformation for you. However, I guess that the compiler team decided that it would be better for the compiler to warn, and ask you to make the change.
Imagine if your original code had read:
if( obj is SpecificClass1 )
{
((SpecificClass1)obj).SomeMethod1();
((SpecificClass1)obj).SomeMethod2();
((SpecificClass1)obj).SomeMethod3();
}
At that point I think you can agree that purely for clarity it is better for the code to be modified by the programmer. At which point, if the code is better written the other way which happens to be more efficient as well as clearer, what is the point of implementing the optimisation?
Upvotes: 3
Reputation: 99869
The second cast may be omitted by an optimizing compiler, but it is not required to do so, and the C# memory model may prevent the application of this optimization in many common cases. If you always use the preferred form with the as
operator, you gain the benefits of this "optimization" regardless of whether the compiler implements special logic to detect and optimize these cases.
Upvotes: 1
Reputation: 22739
To quote Eric Lippert (who used to work on the C# team):
I am asked "why doesn't C# implement feature X?" all the time. The answer is always the same: because no one ever designed, specified, implemented, tested, documented and shipped that feature. All six of those things are necessary to make a feature happen. All of them cost huge amounts of time, effort and money. Features are not cheap, and we try very hard to make sure that we are only shipping those features which give the best possible benefits to our users given our constrained time, effort and money budgets.
Upvotes: 0
Reputation: 22241
After some searching: the answer is in the warning description.
I was right, the compiler is looking for as
expression in this case which would spare you the two casts (is
and ()
cast):
Derived d = new Derived();
Base b = d as Base;
if (b != null)
{
Console.WriteLine(b.ToString());
}
You are actually doing two casts, since the is
is also performing a cast-type operation.
Upvotes: 2