【问题标题】:Cast object to it's parent type with generics使用泛型将对象转换为其父类型
【发布时间】:2020-01-13 14:36:24
【问题描述】:

我正在尝试将一个对象强制转换为该对象派生自它的父类型。

所以,我有这个 ViewModel

public abstract class CostsChargesViewModel<T> where T : CostsChargesBasePage

我有一个派生自它的 FundCostPageViewModel:

public class FundCostPageViewModel : CostsChargesViewModel<FundCostPage>

我有 FundCostPage,它继承自 CostsChargesBasePage

public class FundCostPage : CostsChargesBasePage

所以 - 在拥有 FundCostPageViewModel 实例的上下文中,我希望能够将其转换为 CostChargesViewModel&lt;CostsChargesBasePage&gt;

例如,想象一下这样的 Razor 视图设置:

@model TSC.Website.Core.ViewModel.Pages.FundCostPageViewModel

var foo = Model as CostsChargesViewModel<FundCostPage>; // This would work

var bar = Model as CostsChargesViewModel<CostsChargesBasePage>; // Won't work 

如何将 FundCostPage 的父类转换为 CostsChargesViewModel?

这有点像双重演员 - 本质上是这样做的一种方式:

Model as CostsChargesViewModel<FundCostPage as CostChargesBasePage>

【问题讨论】:

  • 与协方差有关,c#中类不支持协方差
  • 我很确定我以前见过这种情况
  • 您不能将IEnumerable&lt;int&gt; 转换为IEnumerable&lt;Object&gt;,但您可以在IEnumerable&lt;int&gt; 上调用Cast&lt;object&gt;()。根据您对bar 的需求,您也许可以按照这些思路为您的类提供一个方法。

标签: c# generics inheritance casting abstract


【解决方案1】:

这些类至少目前在 C# 中不支持co-variance,并且看不到任何不久的将来会发生这种情况。您可以做的是引入如下界面:

public interface ICostsChargesViewModel<out T> where T : CostsChargesBasePage

你的抽象类会实现它:

public abstract class CostsChargesViewModel<T> : ICostsChargesViewModel<T>  
                                       where T : CostsChargesBasePage

然后你就可以像下面这样写,并且可以正常工作:

var bar = Model as ICostsChargesViewModel<CostsChargesBasePage>; 

See this DEMO Fiddle

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-05-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多