Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 传递基类列表并获取具体类_C#_.net_Oop_Inheritance - Fatal编程技术网

C# 传递基类列表并获取具体类

C# 传递基类列表并获取具体类,c#,.net,oop,inheritance,C#,.net,Oop,Inheritance,我有两个从基类派生的具体类。与混凝土类别B相比,混凝土类别A具有十个附加属性。我有一个方法,其中一个参数是基类列表,如下所示:list。在方法内部,我必须循环遍历列表,并转换到适当的具体类并访问属性。请让我知道如何做到这一点。有什么好的设计模式可以做到这一点吗?c#有一种方法可以研究 您还有is操作符 if (baseClass is derivedClass) { // do what you will with derived class. } 但是 通常你所做的首先是一个糟糕的设

我有两个从基类派生的具体类。与混凝土类别B相比,混凝土类别A具有十个附加属性。我有一个方法,其中一个参数是基类列表,如下所示:
list
。在方法内部,我必须循环遍历列表,并转换到适当的具体类并访问属性。请让我知道如何做到这一点。有什么好的设计模式可以做到这一点吗?

c#有一种方法可以研究

您还有
is
操作符

if (baseClass is derivedClass)
{
    // do what you will with derived class.
}
但是

通常你所做的首先是一个糟糕的设计模式。当您迭代基类,然后将其转换为派生类时,多态性的整个要点就丢失了


也许您可以在基类中创建一个方法,该方法可以执行您需要执行的各种操作

这是基本方法:

foreach(baseClass x in theList)
{
   if (x is classA)
   {
       classA a = (classA) x;
       ...
   }
   else if (x is classB)
   {
       classB b = (classA) x;
       ...    
   }
}
当您需要拆分多个类型时,它不会变得更简单。您可以尝试使用接口或不同的继承模型来避免整个过程。
如果看不到更多细节,就不可能准确地说。

为了避免显式强制转换,我建议您以不同的方式进行:在基类中放置一个抽象方法,该方法将处理具体类的属性

foreach(var baseClass in baseClasses)
{
    if(baseClass.GetType() == typeof(ClassA)
    {
       var myClassA = (ClassA) baseClass;
        dowork();
    }
    else if(baseClass.GetType() == typeof(ClassB)
    {
       var myClassB = (ClassB) baseClass;
        dowork();
    }

}
例如:

public abstract void DoSomethingUsingProperties();
在您的具体类中,使用正确的业务逻辑实现(覆盖)它

然后,在方法中,其中一个参数是基类列表,您可以执行以下操作:

public void YourMethod(List<BaseClass> list, ...other params)
{
    // ...

    foreach(var bc in list)
    {
        // so you don't need to know specific properties of concrete classes...
        bc.DoSomethingUsingProperties();
    }

    //...
}
public方法(列表,…其他参数)
{
// ...
foreach(列表中的var bc)
{
//所以你不需要知道具体类的特定属性。。。
bc.DoSomethingUsingProperties();
}
//...
}
我想C#的类型可能是你在这里的朋友

class BaseClass {}

class ConcreteClass1 : BaseClass
{
    void Display1 () {}
}

class ConcreteClass2 : BaseClass
{
    void Display2 () {}
}

void Enumerate (List<BaseClass> baseItems)
{
    foreach (BaseClass baseItem in baseItems)
    {
        ConcreteAccessor ((dynamic)baseItem);
    }
}

void ConcreteAccessor (ConcreteClass1 concreteItem1)
{
    concreteItem1.Display1 ();
}

void ConcreteAccessor (ConcreteClass2 concreteItem2)
{
    concreteItem2.Display2 ();
}    
类基类{}
类1:基类
{
void Display1(){}
}
类2:基类
{
void Display2(){}
}
无效枚举(列出基本项)
{
foreach(baseItems中的基类baseItem)
{
混凝土存取器((动态)基本项);
}
}
无效混凝土存取器(混凝土类别1混凝土项目1)
{
concreteItem1.Display1();
}
无效混凝土存取器(混凝土类别2混凝土项目2)
{
concreteItem2.Display2();
}    
这里的关键是,每个具体类都有不同的重载,并使用dynamic无缝调用其中一个重载。其美妙之处在于在运行时解决了重载问题,使代码看起来干净

因为它是运行时类型解析,所以不执行编译时验证。假设您错过了某个具体类型的重载,并且运行时将baseItem解析为该具体类型。然后它会导致运行时错误-崩溃-因为没有过载


另一个问题是动态在引擎盖下使用反射。正如您所知,反射会减慢应用程序的速度。

不,您使用
作为
关键字,并检查null,这样可以避免强制转换。不管怎样,像往常一样,在简单的问题上,琼斯凯首先得到了正确的答案。@Baboon,这是一样的@狒狒-我相信这个硬演员将被视为NOP。即使没有,也只是一个很小的问题,而且最初不值得放弃
a
b
的本地声明。这就是我所担心的。你能解释一下基类中方法的性质吗?@user466663在不了解更多问题细节的情况下,解释解决方案的工作原理有点困难Wont compile
typeof
是在编译时计算的。您需要将
typeof(baseClass)
更改为
baseClass.GetType()