OfType访问Generic Parent类

时间:2015-10-08 08:54:16

标签: c# linq generics reflection types

我有以下类/接口:

  • public interface IUiCommand
  • public class StartLandenSynchronisatieUiCommand : IUiCommand; public class SyncGeldverstrekkersUiCommand : IUiCommand;等
  • public class RibbonButtonAggregateViewModel<TCommand> : RibbonButtonViewModel<TCommand> where TCommand : IUiCommand
  • public abstract class RibbonButtonViewModel<TCommand> : ResizableRibbonItem where TCommand : IUiCommand
  • 其他一些已实施的RibbonButtonViewModel

RibbonButtonViewModel包含属性KeyTip

在我正在进行的单元测试中,我有一个包含两个项目的列表:RibbonButtonAggregateViewModel<StartLandenSynchronisatieUiCommand>RibbonButtonAggregateViewModel<SynGeldverstrekkersUiCommand(这只是一个示例,我有更多不同{{1的列表}或其他实现的IUiCommands}类。

我想要的是这个列表为RibbonButtonViewModels所以我可以在for-each中访问他们的RibbonButtonViewModel - 属性。

根据此SO question & answer,我可以正确过滤列表,因此我仍然有两个列表:

KeyTip

即使我正确过滤了列表,并且当// `items` is the list containing the two RibbonButtonAggregateViewModels var correctItems = items.Where(x => { if (!x.GetType().IsGenericType) return false; var baseType = x.GetType().BaseType; if (baseType == null || !baseType.IsGenericType) return false; return baseType.GetGenericTypeDefinition() == typeof (RibbonButtonViewModel<>); }) .ToList(); RibbonButtonViewModels为通用类型时,我们也会获得这两个项目,但我无法获得IUiCommand的结果来访问RibbonButtonViewModels。我尝试在KeyTipWhere之间添加以下两个中的任何一个,但两者都不起作用:

  • ToList - &gt;结果列在空列表中
  • .OfType<RibbonButtonViewModel<IUiCommand>>() - &gt;包含两个.Select(x => x as RibbonButtonViewModel<IUiCommand>)
  • 的列表中的结果

那么,当我有子项列表时,如何获取null的列表来访问RibbonButtonViewModel - 属性。 (PS:没有特别要KeyTip,任何以RibbonButtonAggregateViewModel为基础的实现类都可以,只要列表以RibbonButtonViewModel的形式返回,我就可以访问RibbonButtonViewModels - 属性。

1 个答案:

答案 0 :(得分:1)

一种可能的解决方案是创建一个协变的新界面:

<div class="container">
  <div class="row">
    <div class="col-12-xs">
      <div class="event">
        <div class="date">
        </div>
        <div class="flyer">
        </div>
        <div class="info">
        </div>
      </div>
    </div>
  </div>
</div>

.date, .flyer, .info {
  float: left;
  border: 1px solid black;
  height:100px;
}

.date, .flyer {
  width: 100px;
}

.info {
  min-width: 600px;
}

此界面可由public interface IViewModel<out T> where T : IUiCommand { string KeyTip { get; set; } }

实施
RibbonButtonViewModel

之后你可以使用它:

public abstract class RibbonButtonViewModel<TCommand> : IViewModel<TCommand> where TCommand : IUiCommand
{
    public string KeyTip { get; set; }
}

或者您可以使用动态 - 但您将通过运行时错误替换编译器错误:

var correctItems= items.OfType<IViewModel<IUiCommand>>().ToList()
correctItems[0].KeyTip // is valid

技巧是// `items` is the list containing the two RibbonButtonAggregateViewModels var correctItems = items.Where(x => { if (!x.GetType().IsGenericType) return false; var baseType = x.GetType().BaseType; if (baseType == null || !baseType.IsGenericType) return false; return baseType.GetGenericTypeDefinition() == typeof (RibbonButtonViewModel<>); }) .ToList<dynamic>(); correctItems[0].KeyTip = ""; // will compile but fail at runtime if the type doesn't has such a property.