Reputation: 13
I have several different lists of objects, ie
List<Character> characters;
// ...
and some of those lists are of objects that implement the same interface:
public interface IDebugPrints
// ...
public class Character : IDebugPrints
// ...
I have a class where I would like to store a reference to a list (passed to it in its constructor) that implements IDebugPrints, ie
List<IDebugPrints> inList
So that later I can iterate through that list (in this case to print out debug information about the current entries in the original List).
I can't figure out how to do this. If I pass the List as IEnumerable, it makes a copy of the original list, which dosent work for me since objects are added and removed from the original list after that copy.
Any help is appreciated. I have a feeling this isnt possible based on a few other questions here on SO, but would appreciate confirmation.
EDIT:
Here is a bit more pseudo code:
public interface IDebugPrints
// ...
public class Character : IDebugPrints
// ...
public class StoreList
{
private List<IDebugPrints> internalList;
public StoreList( List<IDebugPrints> inList )
{
internalList = inList;
}
}
// The I have the various lists, for example
List<Character> characters;
// ...
// And I want to pass that list
StoreList sl = new StoreList( characters );
This last line gives compile errors:
Cannot convert from System.Collections.Generic.List<Character> to Systems.Collections.Generic.List<IDebugPrints>
Upvotes: 1
Views: 109
Reputation: 11595
This compiles:
using Microsoft.VisualStudio.TestPlatform.UnitTestFramework;
using System.Collections.Generic;
public interface IDebugPrints
{
}
public class Character : IDebugPrints
{
}
public class StoreList
{
private List<IDebugPrints> internalList;
public StoreList(List<IDebugPrints> inList)
{
internalList = inList;
}
}
[TestClass]
public class Test1
{
[TestMethod]
public void MyTest()
{
var characters = new List<IDebugPrints>();
characters.Add(new Character());
var sl = new StoreList(characters);
}
}
Upvotes: -1
Reputation: 22038
It isn't possible to cast a List<x>
to a List<y>
directly, unless you're using casting methods like:
List<x> listX = listY.Cast<x>();
I would pass the List<Character>
as an IList
to the StoreList.
With the .OfType<>()
extension, you can iterate the childs of the type given.
This way, the list isn't copied.
This way your StoreList
can iterate it, not depending on the types you passed, as long the items are inherited from IDebugPrint
, the ShowAllInfo
will show the Info
.
Here's an example:
public interface IDebugPrints
{
string Info { get; set; }
void ShowInfo();
}
public class Character : IDebugPrints
{
public string Info {get;set;}
public void ShowInfo()
{
Console.WriteLine(Info);
}
}
public class StoreList
{
private IList internalList;
public StoreList(IList inList)
{
internalList = inList;
}
public void ShowAllInfo()
{
// I love the OfType<>() extension, it only returns the items of type IDebugPrints.
foreach (var item in internalList.OfType<IDebugPrints>())
item.ShowInfo();
}
}
class Program
{
static void Main(string[] args)
{
List<Character> characters = new List<Character>();
characters.Add(new Character { Info = "Character 1" });
characters.Add(new Character { Info = "Character 2" });
// And I want to pass that list
StoreList sl = new StoreList(characters);
sl.ShowAllInfo();
Console.ReadKey();
}
}
Upvotes: -1
Reputation: 171178
Pass List<Character> characters
as a IEnumerable<IDebugPrint>
. This works beginning with C# 4.
Make internalList
and inList
typed as IEnumerable<IDebugPrint>
.
Reference types are never copied in C# (except if explicitly implemented and requested by the programmer). .NET has no general way to copy an arbitrary reference type instance.
This means that your variables of type IEnumerable<IDebugPrint>
will refer to the existing modifiable list.
Upvotes: 3