简体   繁体   中英

Polymorphism - Using an object that inherits from an interface rather than the interface directly

In a C# class, is it possible to use a List<T> , where T is a class that implements an interface , but the List<T> is of a class that inherits from the interface , and not from the interface directly?

Here is some code to explain:

public interface ITestClass
{
    List<IListItem> list { get; set; }
}

public interface IListItem
{
    //some data
}

public class ListItem : IListItem
{
    //some data
}

The following code compiles correctly:

public class TestClass : ITestClass
{
    public List<IListItem> list { get; set; }
}

However, the following code does not compile correctly:

public class TestClass : ITestClass
{
    public List<ListItem> list { get; set; }
}

Can someone please explain why, and how I should modify my above code?

The context of the situation is as follows:

I am wanting to serialize a TestClass object to file, however, it cannot be serialized with a List<T> where T is an interface . I still want the ITestClass to specify that the list needs to inherit from IListItem if possible.

Here is the serializtion code that I am using:

IFormatter formatter = new BinaryFormatter(); 

Thanks

You could make your interface take a generic type parameter and constrain it to types of IListItem :

public interface ITestClass<T> where T : IListItem
{
    List<T> list { get; set; }
}

And now your TestClass becomes:

public class TestClass : ITestClass<ListItem>
{
    public List<ListItem> list { get; set; }
}

As we don't know which serialiser you are using, here's an example with XML:

//Set up the object to serialise
var testObject = new TestClass();
testObject.list = new List<ListItem>();
testObject.list.Add(new ListItem());

var serializer = new System.Xml.Serialization.XmlSerializer(typeof(TestClass));
StringWriter sw = new StringWriter();
XmlWriter writer = XmlWriter.Create(sw);
serializer.Serialize(writer, testObject);
var xml = sww.ToString();

And another example now you told us you are using the BinaryFormatter to serialise:

var formatter = new BinaryFormatter();
var stream = new MemoryStream();

//Serialise the object to memory
formatter.Serialize(stream, testObject);

//Reset the position back to start of stream!
stream.Position = 0;

//Deserialise back into a new object
var newTestObject = (TestClass)formatter.Deserialize(stream);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM