我有几个派生类都来自同一个基类。
class Base {}
class ClassOne : Base {}
class ClassTwo : Base {}
class ClassThree : Base {}
假设我有这些类对象的数组,我需要遍历此数组并根据派生类类型执行特定操作。
Base[] objects;
foreach(Base entry in objects){
//Check for class type to perform operations
}
我已经看了几种方法来解决这个问题。起初我尝试了catch块然后尝试施放捕获无效强制转换的对象然后尝试另一个强制转换。这看起来很乱,所以我试着做一次检查。
if(entry.GetType() == ClassOne){}
else if(entry.GetType() == ClassTwo){}
但这不起作用,因为它们都被认为是代码中该实例的Base类型。
我现在要解决的问题是添加一个包含所有派生类类型的枚举,并在创建对象时将其设置在构造函数中。
public enum DerivedClassType{
Base,
One,
Two,
Three
}
现在我的foreach有一个开关,可以在尝试施放之前检查该类型。
Base[] objects;
foreach(Base entry in objects){
switch(entry.derivedClassType){
case DerivedClassType.One:
((One)entry).DoOneStuff();
break;
case DerivedClassType.Two:
break;
case DerivedClassType.Three:
break;
}
}
在完成所有这些步骤之后,我想知道处理这类问题的正确方法是什么,因为这一切似乎都比它应该更复杂。
由于
答案 0 :(得分:3)
根据类类型执行不同操作的正确方法是使用抽象方法。
abstract class Base
{
public abstract void DoSomethingWithArg(string arg);
}
class ClassOne : Base
{
public override void DoSomethingWithArg(string arg)
{
Console.WriteLine($"Class One says {arg}");
}
}
class ClassTwo : Base
{
public override void DoSomethingWithArg(string arg)
{
Console.WriteLine($"Class Two says {arg}");
}
}
然后像这样使用它
Base[] objects;
foreach (Base entry in objects)
{
entry.DoSomethingWithArg("Hello");
}
如果你真的想继续沿着潜在的不可维护代码的路径前进,你可以像这样实现它(需要C#6);
foreach (Base entry in objects)
{
switch (entry.GetType().Name)
{
case (nameof(ClassOne)):
// Do something
break;
case (nameof(ClassTwo)):
// Do something else
break;
}
}
答案 1 :(得分:0)
这应该有效:
my_file = open('configs.txt', 'r')
license = []
for line in my_file:
if line.startswith ("show license verbose"):
license.append(line)
for (i, line) in zip( range(1, 6), my_file ):
license.append( line )
print( license )
答案 2 :(得分:0)
你指出带有重写方法的类型层次结构不是每个问题的答案。
你可能会考虑一种更具功能性的方法,它比可以在switch语句或ifs系列中调用函数方法更具可读性,可测试性,并且我认为是可维护的。我给你留下了这个解决方案(你可以在这里玩它:https://repl.it/C59q/3):
using System;
using System.Collections.Generic;
class Base {}
class ClassOne : Base {
public void doOne(){
Console.WriteLine("doing one") ;
}
}
class ClassTwo : Base {
public void doTwo(){
Console.WriteLine("doing two");
}
}
class ClassThree : Base {
public void doThree(){
Console.WriteLine("doing three");
}
}
class MainClass {
static Base[] objects = {
new ClassOne(),
new ClassTwo(),
new ClassThree()
};
public static void Main (string[] args) {
Action<ClassOne> ClassOneFunc = delegate(ClassOne o)
{o.doOne();};
Action<ClassTwo> ClassTwoFunc = delegate(ClassTwo o)
{ o.doTwo();};
Action<ClassThree> ClassThreeFunc = delegate(ClassThree o)
{ o.doThree();};
var contents = new Dictionary<System.Type, Action<dynamic>>
{
{typeof(ClassOne), ClassOneFunc},
{typeof(ClassTwo), ClassTwoFunc},
{typeof(ClassThree), ClassThreeFunc},
};
Action<dynamic> worker = o => contents[o.GetType()](o);
foreach(var each in objects){
worker(each);
}
}}