Difference in cast using "as" and "type cast"

Asked

Viewed 211 times

5

A question arose about casting in C#, I see in many fonts using the cast in the following ways.

What is the difference between one and the other, when using one way or another?

public interface InterfaceTeste
{
    int Id { get; set; }
}

public class ClasseTeste : InterfaceTeste
{
    public int Id { get; set; }
    public string Nome { get; set; }
}

public class ClasseTestando
{
    public void Teste()
    {
        List<InterfaceTeste> objList = new List<InterfaceTeste>();
        for (var i = 0; i < 0; i++)
        {
            objList.Add(new ClasseTeste() { Id = i, Nome = "Nome" + 1 });
        }
        ClasseTeste classe1 = objList.Find(x => x.Id == 1) as ClasseTeste;
        ClasseTeste classe2 = (ClasseTeste)objList.Find(x => x.Id == 1);
    }
}
  • When you do the conversion using "as", if the code fails to do the conversion returned a null value and when you do the normal cast if the program fails to do the conversion will be returned an Exception.

2 answers

5


In this example neither of the two is necessary, so it makes no difference.

as

The operator as should be used when you are not sure that the operation will work. Consider that there will be a conversion attempt, but if the object that should receive the value of that type fails, it will receive the null value. After using the as It is essentially mandatory to check if the object is not null. Then you would. If you’re not doing this check you probably didn’t need this one casting, or you’ll have another mistake later, which could be a bigger problem finding out what’s going on.

The cost of that operator as is even smaller, but when we make the check if it is not null ends up getting more or less the same thing.

C# 6

Normally you would make a if to check if the value is null to decide what to do. In C# 6 there is an operator that does nothing if it is null. In some cases it is possible to use it to simplify the code, but not at all.

C# 7

It is possible to use Pattern matching and only create a new object when it confirms that the object type is the one expected.

C# 8

In this version that no longer encourages the use of null types, therefore the as should fall into disuse and give way to the Pattern matching. The cast in parentheses will still be useful.

Cast

The cast classic, the second, requires you to be absolutely sure that the "conversion" will not fail. Any situation you will know that it will not fail you can use it. In many cases the cost of using it is zero.

One of the ways to be absolutely sure is to make a if before doing the cast, but if you do this it is because you should use the as. Be sure, if you need to check, it is because you do not have it. If you do this the performance will be worse and you can enter race condition.

This is a case you are only informing to the compiler that you can ensure that the type is the one the compiler expects. If your warranty does not conform at runtime the application will throw an exception that should not be handled, this is a programming error and must fix this error.

It also has the advantage of making conversions in type by value. These types cannot be null, so the as would not work. Of course it does not include the types by value.

It can do type conversions when it is implemented on the type itself. The operator () can be implemented in explicit conversion types (it is also possible implicitly where an operator is not used). The as is only allowed where the language leaves naturally, in natural conversions, usually just making a derivative type turn into a base type of it.

I won’t say it’s never necessary, but for the future I would forget the as.

3

When you cast with the operator (), if conversion fails an exception of type will be returned InvalidCastException. Already when the keyword as is used, if the conversion fails the result will be null. Hence the keyword as can only be used with reference types or types nullable.

See the following links:

Difference between cast and as - C#
https://cbsa.com.br/post/diferenca-entre-cast-e-as---c.aspx

as (Reference of C#)
https://docs.microsoft.com/pt-br/dotnet/csharp/language-reference/keywords/as

Operator () (Reference of C#)
https://docs.microsoft.com/pt-br/dotnet/csharp/language-reference/operators/invocation-operator

Cast conversions and type conversions (C Programming Guide#)
https://docs.microsoft.com/pt-br/dotnet/csharp/programming-guide/types/casting-and-type-conversions

And, from C# 7, it is also possible to use the keyword is, both to test the type and to make a conversion, thus:

string s = null;
if (objList.Find(x => x.Id == 1) is ClasseTeste ct)
{
   s = $"Id: {ct.Id}, Nome: {ct.Nome}";
}

is (reference of C#)
https://docs.microsoft.com/pt-br/dotnet/csharp/language-reference/keywords/is

Browser other questions tagged

You are not signed in. Login or sign up in order to post.