Because I would do Downcasting and Upcasting on C#

Asked

Viewed 70 times

2

To be more specific, I understood the concepts and everything, but I don’t have a real-life example that I would need to do upcasting or downcasting, for example

Businessaccount inherits from Account

Businessaccount : Account

Account ac1 = new BusinessAccount();

'Cause I’d do it, if it’s simpler for me to do it

BusinessAccount ac2 = new BusinessAccount();
  • Related: https://answall.com/questions/449584/upcasting-e-downcasting-subsequente-permite-acessar-o-attributedo-typo-original/449650#449650

  • Downcasting, mostly because there is design error. The most common when they explain about it teach to design wrong. Yes, most of the libraries and frameworks you use have design error. Almost always have better solution if the project is well done. Some of the answers below teach you to cast where you don’t need to or don’t teach you to cast, or talk about a cast you didn’t need to cast (the question doesn’t help). I am running out of time to prepare a full answer. Relacionados: https://answall.com/q/286192/101 e https://answall.com/q/131091/101.

  • I will look at all the links and thank you for the effort to help

3 answers

2


I will use the names of the classes you put in the question. We have the following classes:

The base class Account:

internal class Account
{
    internal int AccountNumber { get; set; }
}

And two classes they inherit from it. A class for business accounts:

internal class BusinessAccount : Account
{
    internal string BusinessName { get; set; }
    internal decimal Revenue { get; set; }
}

And one for organizations:

internal class OrgAccount : Account
{
    internal string OrganizationName { get; set; }
}

Classes differ in the category of properties, so they can be used in code for more specific and different things.

Make a downcasting is useful in the example of a method GetAccount(int accountNumber) that can return any type of account, be it BusinessAccount or OrganizationAccount.

However, as each one differs in its properties, we need to treat them in different ways. For this we can use the following conversion, as in the example below:

// Não temos certeza de qual é o tipo que está retornando (Account, Business ou Organization)
Account account = GetAccount(accountNumber: 93840303);

// Verificando o tipo que retornou do método GetAccount
if (account is BusinessAccount) 
{
    // downcast para um tipo mais específico
    var businessAccount = (BusinessAccount)account;

    // recebe apenas o tipo BusinessAccount
    ManageBusinessAccount(businessAccount); 
} 
else if (account is OrganizationAccount) 
{
    // downcast para um tipo mais específico
    var orgAccount = (OrganizationAccount)account;

    // recebe apenas o tipo OrganizationAccount
    ManageOrganizationAccount(orgAccount);
} 
else 
{
    //...
}

See that the downcasting is necessary in this scenario since the methods ManageBusinessAccount and ManageOrganizationAccount do not receive the base type as argument.

But in case we have a method ManageAccount which receives only the base type Account as argument, we can pass any of the types:

OrganizationAccount orgAccount = (OrganizationAccount)account;
ManageAccount(account); // Este método recebe apenas o tipo Account como argumento

So much for the guy BusinessAccount as to the type OrganizationAccount implement the base class. That is, the upcasting is "implicit".

1

Let me give you an example that is not specific to C# but occurs in every framework with graphical interface. Each element on the screen is a View. There are elements composed of subviews, that is, containing objects View subordinates. The window itself is a super View containing directly or indirectly all other.

There are Views of various types: TextView, ButtonView, ImageView, LabelView... (the exact names will depend on the language and framework). All these classes descend from View and share a basic implementation that allows them to appear on the screen.

Add a subview to a View is an example of "upcasting" - no matter the final subview type, it is treated by the parent view as View, simply.

Now, another situation: an event handler receives the object View that triggered the event. But I know that this object is actually a ButtonView, and as part of the response to the event, I want to call a method that only exists in the class ButtonView. So I have to do a "downcasting" of View for ButtonView.

I can do this even optionally, using operators is or as to test whether downcasting will work, or to deal with the case of the object View can be of different sub-classes and the event treatment should behave differently for each sub-class.

  • Thank you for the reply

1

Let’s see if I can help you.

Setting:

Imagine that you are developing a game. In this game you present on screen some types of animals (Lion, Zebra, Man, Frog, Kangaroo, etc). All these animals inherit behavior runs class Animal. Soon we will have the following definitions.

public class Animal
{
   public virtual void corre(){}
}

public class Homem : Animal
{  
  public override void corre(){
      Console.WriteLine("Alternando Pernas");
  }
}

public class Sapo: Animal
{
   public override void corre(){
      Console.WriteLine("Pulando");
  }
}

ETC ...

With these settings imagine that on the screen when someone is playing you would have a list of animals running during the game. Instead of you going through a specific list of each animal to present the same running, you could have an Animal type list containing all the animals that will be part of the scenario. So, to give action to all the bugs you could have the code below:

var animais = new List<Animal> { new Homem(), new Sapo(), etc ... };

foreach (Animal a in animais )
{
    a.corre();
}

That would be enough for all the animals to move on the screen

Instead of doing:

 var homens= new List<Home> { new Homem(), new Homem(), etc ... };
 var sapos= new List<Sapo> { new Sapo(), new Sapo(), etc ... };  

foreach (homens in homem)
{
    homens.corre();
    sapos.corre();
}

The example is purely inslustrative. But, the name of the concept you need to understand is polymorphism and this property is used to address the most diverse modeling problems. All this will become clearer when you study project patterns. Maybe Strategy is the simplest of you to understand the concept of polymorphism.

I hope I’ve helped.

OBS: Obviously this concept should not be used indiscriminately and in any way. It is very common to apply polymorphism together with iteroids.

  • Thank you for the reply

Browser other questions tagged

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