2

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;
});
Amal K
  • 4,359
  • 2
  • 22
  • 44
Guy E
  • 1,775
  • 2
  • 27
  • 55
  • Does this answer your question? [Is casting the same thing as converting?](https://stackoverflow.com/questions/143997/is-casting-the-same-thing-as-converting) It's the same object, just stored as the more basic (less derived) type – Charlieface Jun 13 '21 at 09:30
  • Just wondering why this would be a problem. – Gert Arnold Jun 13 '21 at 18:58
  • @GertArnold - it's a problem because I would like to expose a base class structure – Guy E Jun 14 '21 at 03:44
  • Yeah. obviously, but I don't see why you can't if you cast to BaseClass. There's some underlying problem here that you don't mention ("XY problem"). – Gert Arnold Jun 14 '21 at 06:49

2 Answers2

1

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

Amal K
  • 4,359
  • 2
  • 22
  • 44
1

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

Yiyi You
  • 16,875
  • 1
  • 10
  • 22