Reputation: 4551
Casting does not make copies of objects. More concretely IEnumerable.Cast, according to this resource, which makes total sense. However for this app, find fiddle, reference equals is false if I change the log at the end from the Cast<BaseClass>
to Cast<DerivedClass1>
. Check logs at the main program.
are equal: True areEqualRef: True areEqualRef: False
Posting the code, just in case, omit it of you get my point playing around with the fiddle :)
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
namespace ConsoleApp17
{
public class BaseClass {
string name = "I am base";
public Type type;
public enum Type {
a,b,c,d
}
public BaseClass(Type type) {
this.type = type;
}
}
public class DerivedClass1 : BaseClass
{
string name = "I am derivedA";
public DerivedClass1(): base(Type.a) {
}
}
public class DerivedClass2 : BaseClass
{
string name = "I am derivedB";
public DerivedClass2() : base(Type.b)
{
}
}
public class Foo
{
public Dictionary<BaseClass.Type, List<BaseClass>> dict = new Dictionary<BaseClass.Type, List<BaseClass>>();
public Foo() {
dict[BaseClass.Type.a] = new List<BaseClass>();
dict[BaseClass.Type.b] = new List<BaseClass>();
dict[BaseClass.Type.c] = new List<BaseClass>();
dict[BaseClass.Type.d] = new List<BaseClass>();
AddItem(new DerivedClass1());
AddItem(new DerivedClass1());
AddItem(new DerivedClass2());
AddItem(new DerivedClass2());
AddItem(new DerivedClass2());
}
public IEnumerable<T> GetEnumByType<T>(BaseClass.Type type) where T : BaseClass
{
if (dict.ContainsKey(type))
{
if (type == BaseClass.Type.a)
{
Console.WriteLine($"are equal: { object.ReferenceEquals(dict[type].Cast<T>(), dict[BaseClass.Type.a])}");
}
return dict[type].Cast<T>();
}
return null;
}
public void AddItem<T>(T item) where T : BaseClass
{
dict[item.type].Add(item);
}
}
class Program
{
static void Main(string[] args)
{
Foo foo = new Foo();
IEnumerable myList = foo.GetEnumByType<BaseClass>(BaseClass.Type.a);
Console.WriteLine($"areEqualRef: {object.ReferenceEquals(foo.dict[BaseClass.Type.a].Cast<BaseClass>(), foo.dict[BaseClass.Type.a])}");
Console.ReadLine();
}
}
}
Update: Updated the fiddle with both logs to avoid the need of copy/pasting
Upvotes: 2
Views: 40
Reputation: 1063774
You need to notionally separate what is being compared here. When it says that Enumerable.Cast<T>
doesn't make copies of objects, it is talking about the individual objects in the sequence. Not the sequence itself. In order to perform the necessary reshaping, the sequence returned from the Cast<T>
method is a different wrapper/decorator instance over the original sequence.
Since you're using ReferenceEquals
on the sequence, this will report false
. However, if you were to compare each object from the sequences (pairwise in turn), you would find that those were the same objects.
Upvotes: 3