C# 处理抽象类的不同实现的集合的干净方法?

C# 处理抽象类的不同实现的集合的干净方法?,c#,abstract-class,implementation,C#,Abstract Class,Implementation,我有几个抽象类,它们在我的项目中具有一些UserControls的核心功能。我还有两个独立的实现,都是从抽象类派生的;让我们把它们称为AbstractImpl1和AbstractImpl2.此外,我还有抽象UserControls的集合,我在几个地方迭代了这些集合 我遇到的问题是InvalidCastExceptions-我需要迭代实现,而不是Abstract用户控件,以获得某些属性(可视化)。除了做一个try/catch,还有什么干净的方法来处理这个问题吗 示例: 在我的项目中,我有抽象类:A

我有几个抽象类,它们在我的项目中具有一些
UserControls
的核心功能。我还有两个独立的实现,都是从抽象类派生的;让我们把它们称为
AbstractImpl1
AbstractImpl2.
此外,我还有
抽象
UserControls
的集合,我在几个地方迭代了这些集合

我遇到的问题是
InvalidCastExceptions
-我需要迭代实现,而不是Abstract用户控件,以获得某些属性(可视化)。除了做一个
try/catch
,还有什么干净的方法来处理这个问题吗

示例:

在我的项目中,我有抽象类:
AbsUserControl
然后我有两个独立的实现:
AbstractImpl1
AbstractImpl2

在我的主要表单中,我有
ObservableCollection absControlCollection
,然后遍历我所做的
foreach(absControlCollection中的AbstractImpl1 userControl)
,以便能够访问视觉方面。问题是,
observateCollection absControlCollection
可以由
AbstractImpl1
AbstractImpl2
对象组成

有没有一个干净的方法来处理这个问题?现在,我在
absControlCollection
中迭代对象的每个地方都有一个
try/catch
块,试图迭代
AbstractImpl1
对象,然后捕获
InvalidCastException
并继续迭代
AbstractImpl2
对象

如果需要更多信息,请告诉我。谢谢

用于为您执行过滤:

foreach(AbstractImpl1 userControl in
    absControlCollection.OfType<AbstractImpl1>())
{
    ...
}
中的foreach(AbstractImpl1用户控件) absControlCollection.OfType()) { ... }
用于为您执行过滤:

foreach(AbstractImpl1 userControl in
    absControlCollection.OfType<AbstractImpl1>())
{
    ...
}
中的foreach(AbstractImpl1用户控件) absControlCollection.OfType()) { ... }
您可以使用LINQ的方法安全地筛选出您感兴趣的具体实现。您的
foreach
将如下所示:

foreach(var userControl in abcControlCollection.OfType<AbstractImpl1>())
{
    /* ... */
}
foreach(abcControlCollection.OfType()中的var userControl)
{
/* ... */
}

您可以使用LINQ的方法安全地筛选出您感兴趣的具体实现。您的
foreach
将如下所示:

foreach(var userControl in abcControlCollection.OfType<AbstractImpl1>())
{
    /* ... */
}
foreach(abcControlCollection.OfType()中的var userControl)
{
/* ... */
}

类型的
的替代品;铸造无例外:

foreach(AbsUserControl control in absControlCollection)
{
    if(control is AbstractImpl1)
    {
        AbstractImpl1 i1 = (AbstractImpl1)control;
        DoStuff(i1);
    }
    if(control is AbstractImpl2)
    {
        AbstractImpl2 i2 = (AbstractImpl2)control;
        DoOtherStuff(i2);
    }
}

类型
的的替代品;铸造无例外:

foreach(AbsUserControl control in absControlCollection)
{
    if(control is AbstractImpl1)
    {
        AbstractImpl1 i1 = (AbstractImpl1)control;
        DoStuff(i1);
    }
    if(control is AbstractImpl2)
    {
        AbstractImpl2 i2 = (AbstractImpl2)control;
        DoOtherStuff(i2);
    }
}

你的意思是说集合是全部
Impl1
还是全部
Impl2
,从来都不是混合的吗?@Rawling现在的集合是
Impl1
Impl2
,但我以后可能想要一个混合的集合,你的意思是集合是全部
Impl1
或全部
Impl2
,从来没有混合过?@Rawling现在收集的是
Impl1
Impl2
,但可能我以后会想要混合收集!尽管Rawling的答案是“更干净”,但这实际上更好地满足了我的需求-两个实现之间的
foreach()
循环中的许多逻辑是通用的,因此我更应该检查
foreach()
中的哪个实现,执行特定的逻辑,然后继续使用公共逻辑,而不是使用单独的
foreach()
循环,这将迫使我重复逻辑。谢谢!尽管Rawling的答案是“更干净”,但这实际上更好地满足了我的需求-两个实现之间的
foreach()
循环中的许多逻辑是通用的,因此我更应该检查
foreach()
中的哪个实现,执行特定的逻辑,然后继续使用公共逻辑,而不是使用单独的
foreach()
循环,这将迫使我重复逻辑。谢谢!这是一个非常干净的实现,但是@SebastianNegraszus的解决方案实际上更好地满足了我的特定需求。是的,我可能也会选择他的解决方案:pThanks!这是一个非常干净的实现,但是@SebastianNegraszus的解决方案实际上更好地满足了我的特定需求。是的,我可能也会选择他的解决方案:p