2015-10-14 60 views
1

我正在构建一个简单的德语学习帮助程序,其中一个元素是字典。为了管理所有单词,我添加了三个类:Noun,AdjectiveVerb。它们都从另一个抽象类Word继承。名词类还包含一个Article枚举。 所有单词(形容词,名词和动词对象)都存储在一个List<Word> ..我无法在ListView列或更具体地打印它们 - 访问我想要的字段。C#在超类对象上操作时获取对子类变量的访问

基本上,我想遍历列表中的所有单词。在做这件事时,检查当前项目是否是名词(名词类型的对象) - 如果是,请获取其文章。如果不是,打印“ - ”,然后将单词翻译添加到列。

这里是方法:

private void UpdateList(List<Word> currentWordList) //passing the List 
{ 
    wordsListView.Items.Clear(); 
    int index = 1; // first column of the number 

    foreach (Word w in currentWordList) 
    { 
     ListViewItem newItem = new ListViewItem("" + index); 
     if (w is Noun) 
      newItem.SubItems.Add(w.Article); //here is the error (no definition for "Article") 
     else 
      newItem.SubItems.Add("--"); 

     newItem.SubItems.Add(w.GermanTranslation); 
     newItem.SubItems.Add(w.PolishTranslation); 

     wordsListView.Items.Add(newItem); 
    } 
} 

如何解决这个问题?

非常感谢您的帮助。

+0

考虑在GUI元素上使用数据绑定。覆盖''ToString()'的类(如'Word'及其子类),你想要保存在列表中。当GUI元素实际上*是实际数据时,许多事情变得更加容易。 –

+0

您试图违反面向对象设计的一些基本原则。超类不应该对某个特定的子类有任何依赖。如果子类可以实现哪些超类需要调用的功能,则将功能抽象化并在子类中实现它。 – David

+0

@大卫苛刻的话。您认为OP如何试图将“对特定子类的依赖”引入超类? (依赖/知识将在此处引入GUI控制代码,imo。) –

回答

5

你可以施放wNoun这样的:

Noun noun = (Noun)w; 

然后使用noun变量访问Article

说了这样的话,更好的方法是在Word中定义一个抽象方法,名为GetDescription,它可以获取单词的描述。

下面是一个例子:

public abstract class Word 
{ 
    public abstract string GetDescription(); 
    //.... 
} 

public class Noun : Word 
{ 
    public override string GetDescription() 
    { 
     //Here you can access the Article property 
     //... 
    } 
    //... 
} 

然后在循环中,你可以使用GetDescription方法来获取每个字的说明。

+0

你可能会将第一个陈述改为“你*可以*演员,如果你真的想......”,因为演员绝对不是OP“应该”做的。这个答案的其余部分是OP *应该做的:) – David

+0

非常感谢! @David - 为什么演员是我不应该做的事情?我是一名新秀,如果在这种情况下施放是一种不好的做法,我很想知道为什么;)谢谢! – Dandry

+0

@Dandry:查看“S.O.L.I.D.”面向对象设计的原则。这与Liskov替代原则特别相关。在这种情况下,转换是在对象的实现细节“窥探下”,而不是仅使用其暴露的接口。这会造成紧密耦合,并使代码非常难以维护。铸造有其用途,但这不是其中之一。 – David

1

您需要将W转换为子类。像这样

newItem.SubItems.Add(((Noun)w).Article) 
+0

谢谢你的帮助! – Dandry