Guy E
Guy E

Reputation: 1927

Cast and convert to a collection of base class objects not working

I'm trying to do a very simple thing - casting a static list of inherited class objects to a list of base class objects. For some reason - in the result, I always get the inherited class objects. I can see that it isn't converting even when debugging inside the lambda expressions. What Am I missing here ?

See my code:

This is the class that contains the static property:

public class InheritedClassRepository
{
    public static List<InheritedClass> RepoItems { get; set; }
}

This is the Inherited class:

public class InheritedClass: BaseClass
{
public InheritedClass() { }
public string someProperty { get; set; }
}

This is the base class:

public class BaseClass
{
    public BaseClass() { }

    public int DeviceId { get; set; }
    [JsonProperty("Id")]
    public int Id
    {
        get //For scheme reasons
        {
            return DeviceId;
        }
    }    
}

These are all the castings and conversions I've tried:

List<BaseClass> a = InheritedClassRepository.RepoItems.Select(item =>
{
    BaseClass A = (BaseClass)item;
    return A;
}).ToList();

List<BaseClass> b = InheritedClassRepository.RepoItems.Select(item =>
{
    BaseClass A = item as BaseClass;
    return item as BaseClass;
}).ToList();
List<BaseClass> c = InheritedClassRepository.RepoItems.ConvertAll(item =>
{
    BaseClass A = (BaseClass)item;
    return (BaseClass)item;
});


List<BaseClass> e = InheritedClassRepository.RepoItems.Cast<BaseClass>().ToList();

List<BaseClass> f = InheritedClassRepository.RepoItems.ConvertAll(item =>
{
    BaseClass A = (BaseClass)item;
    return (BaseClass)item;
});

Upvotes: 2

Views: 523

Answers (2)

Yiyi You
Yiyi You

Reputation: 18189

You can try to use the following code:

List<BaseClass> a = InheritedClassRepository.RepoItems.Select(item =>
            {
                BaseClass A = new BaseClass {DeviceId=item.DeviceId};
                return A;
            }).ToList();

result: enter image description here

Upvotes: 1

Amal K
Amal K

Reputation: 4919

While you are up-casting and down-casting within the type hierarchy, the true runtime type of the object remains intact. What you are doing is called a reference conversion. It only changes the type of the reference that points to the object in memory. The actual object remains untouched. Unlike value types, where type conversion involves changing the object identity, like an int to float conversion, casting only changes the type of the reference.

From the Microsoft Docs C# Language Reference:

Reference conversions, implicit or explicit, never change the referential identity of the object being converted. In other words, while a reference conversion may change the type of the reference, it never changes the type or value of the object being referred to.

If you are logging the list elements to the console and seeing InheritedClass, it is because Object.ToString() is defined like this:

public virtual String ToString()
{
    return GetType().ToString();
}

From https://github.com/microsoft/referencesource/blob/master/mscorlib/system/object.cs

GetType() retrieves the true runtime type of the object, regardless of its reference

Upvotes: 1

Related Questions