N3wbie
N3wbie

Reputation: 227

C# Casting between objects of different types

First of all I'm new to C#.
The error I get is:

Additional information: Unable to cast object of type 'UserGUI.MyItems' to type 'CommonBookLib.AbstractItem'.

They are 2 different classes:

public class MyItems
{
    public string ItemName { get; set; }
    public int CopyNumber { get; set; }
    public int Guid { get; set; }
    public DateTime? TimePrinted { get; set; }
    public string Category { get; set; }
    public string SubCategory { get; set; }
    public bool? BestSeller { get; set; }
}

and

public class AbstractItem : IPropsDetails
{
    public int CopyNumber { get; }
    public string ItemName { get; }
    public DateTime Time { get; }
    public int Guid { get; }

    public AbstractItem(int copyNumber, string itemName, DateTime time, int guid)
    {
        this.CopyNumber = copyNumber;
        this.ItemName = itemName;
        this.Time = time;
        this.Guid = guid;
    }
}

It happens when I do:

AbstractItem myItemsList = (AbstractItem)LibraryList.SelectedItem;
logicManager.Remove(myItemsList);

Well, as you can see, I have MyItems which are responsible for the DataBindings in my GUI and AbstractItem which responsible for implementing an addition operation to where my data is saved.

Since I did not managed my code well I got into this situation and I really do not want to change MyItems (delete and recode AbstractItem). How can I Convert the two?

By the way, I know AbstractItem has only 4 properties while MyItems has more.

However, I have children with the exact same properties of AbstractItem.

Any help would be appreciated. Thanks in advance!

Upvotes: 0

Views: 97

Answers (3)

Crowcoder
Crowcoder

Reputation: 11514

You seem to need a mapper more than a cast. Look at AutoMapper or write your own routine as suggested by habibhassani. Also, Grant's answer is very good. But your question was about casting so here I show how you can implement a casting operator so that your cast would work. This is not a technique you should reach for lightly. It puts a dependency on AbstractItem directly in MyItems and it is not the most discoverable pattern for maintainers of your code.

public class MyItems
{
    public string ItemName { get; set; }
    public int CopyNumber { get; set; }
    public int Guid { get; set; }
    public DateTime? TimePrinted { get; set; }
    public string Category { get; set; }
    public string SubCategory { get; set; }
    public bool? BestSeller { get; set; }

    public static explicit operator AbstractItem(MyItems myitems)
    {
        return new AbstractItem(myitems.CopyNumber, myitems.ItemName, myitems.TimePrinted, myitems.Guid);
    }
}

A couple more observances. Naming your class AbstractItem is confusing, it implies that it is actually abstract but it is not.

Guid is a poor name for a property because it is already a Type. You have something named Guid that is an int - confusing.

Upvotes: 0

habibhassani
habibhassani

Reputation: 506

You can make MyItems inherit AbstractItem, or make a method that handle the conversion between them.

Upvotes: 0

Grant Winney
Grant Winney

Reputation: 66449

Remove fields from the MyItems class that are also present in AbstractItem, and then have MyItems derive from it instead.

You'll have to add a constructor to MyItems that passes the required values to the base constructor, or add an empty constructor to the base class.

public class MyItems : AbstractItem
{
    public MyItems(int copyNumber, string itemName, DateTime time, int guid)
        :base(copyNumber, itemName, time, guid)
    {
    }

    public DateTime? TimePrinted { get; set; }
    public string Category { get; set; }
    public string SubCategory { get; set; }
    public bool? BestSeller { get; set; }
}

Upvotes: 5

Related Questions