派生类设计问题(多态)
设计问题如下,实际问题由2个模块组成。
模块 1 类(外部组件)
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; }
}
模块 2 类
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
}
}
本质上派生类是在模块 2 中生成的,并在外部组件模块 1 中处理(a/c 参考丢失)。
这是将模块 2 的派生类对象转换为模块 1 类对象的唯一方法,
我希望我已经清楚地解释了这个问题,如果没有,我深表歉意,非常感谢解决这个问题。
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
如果我正确理解您的问题,您想要的是将
IList
视为IList
。这在 C# 中是不可能的,并且有很好的理由:IList
说可以做的事情之一是“尝试将任何LetterA
添加到它。这对于IList
是不可能的,因此没有内置的方法可以完成您想要的操作。您可以做的是创建您自己的
IList
实现,它包装派生类型的另一个IList
:(class
约束不是必需的,但可以使一些代码更简单。)您的
ALetters
的 setter 可能如下所示: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 anyLetterA
to 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
class
constraints are not necessary, but make some code simpler.)Your setter for
ALetters
could then look like this: