The design problem is as follows, actual problem consists of 2 modules.
Module 1 classes (External Assembly)
abstract class Letter
{
private int _id;
protected Letter(int id) { _id = id; }
public abstract string Val { get; }
}
class LetterA : Letter
{
public LetterA(int id) : base(id) {}
public override string Val
{
get { return "A"; }
}
}
class WordWithALettersOnly
{
public IList<LetterA> ALetters { get; set; }
}
Module 2 classes
class LetterSmallA : LetterA
{
public LetterSmallA(int id) : base(id) {}
public override string Val
{
get { return "a"; }
}
}
class WordWithSmallALettersOnly : WordWithALettersOnly
{
private IList<LetterSmallA> _aLetters;
public new IList<LetterSmallA> ALetters
{
get { return _aLetters; }
set
{
_aLetters = value;
if(_aLetters != null)
base.ALetters = value.Cast<LetterA>().ToList(); // <-- reference lost
}
}
}
class Program
{
static void Main(string[] args)
{
var smallAWordOnly = new WordwithSmallALettersOnly();
smallAWordOnly.ALetters = new List<LetterSmallA>(){new LetterSmallA(1)};
Console.WriteLine("d : " + smallAWordOnly.ALetters.Count); // --> 1
Console.WriteLine("b : " + ((WordwithALettersOnly)smallAWordOnly).ALetters.Count); // --> 1
smallAWordOnly.ALetters.Add(new LetterSmallA(2)); --> 2
Console.WriteLine("d : " + smallAWordOnly.ALetters.Count);
Console.WriteLine("b : " + ((WordwithALettersOnly)smallAWordOnly).ALetters.Count); // -> 1
}
}
Essentially derived classes are generated in the module 2 and processed in the external assembly module 1, on a/c reference loss.
Is the only way to translate the derived class objects of the module 2 to module 1 class objects
I hope i have been explain clearly the issue, if not i do apologise, would really appreciate solutions to this.
If I understand your question correctly, what you want is to treat
IList<LetterSmallA>asIList<LetterA>. This is not possible in C# and for very good reasons: one of the thingsIList<LetterA>says is possible to do with is is to “try to add anyLetterAto it. This is not possible withIList<LetterSmallA>and so there is no built-in way to do what you want.What you can do is to create your own implementation of
IList<T>that wraps anotherIList<T>of derived type:(The
classconstraints are not necessary, but make some code simpler.)Your setter for
ALetterscould then look like this: