如何将数据强制转换为方法约束中指定的泛型?

时间:2018-01-25 08:18:51

标签: c# generics

我有以下数据类和VM类:

public interface IData
{
    string Name
    {
        get;
    }
   }

public class DataPartial: IData
{

    public DataPartial()
    {


    }

    public string Name => "Data partial";
}

public class DataFull : IData
{
    public string Name => "Data full";

    public DataFull()
    {

    }
}

public interface IVM
{
    IData Data { get; }
}
public interface IVM_partial: IVM
{
  new  DataPartial Data { get; }
}


public class VM_Partial : IVM_partial
{
    public VM_Partial()
    {
        Data = new DataPartial();

    }
    public DataPartial Data { get; set; }

    IData IVM.Data => Data;
}
public interface IVM_Total:IVM_partial
{
   new DataFull Data { get; }
}



public class VM_Total : IVM_Total
{


    public VM_Total(IVM_partial dataA)
    {
        Data = new DataFull();
        DataA_interface = dataA;
    }

    public IVM_partial DataA_interface { get; }


    public DataFull Data { get; private set; }

    DataPartial IVM_partial.Data => DataA_interface.Data;

    IData IVM.Data => Data;
}

public static class RunVM<T, VM>
    where T: class, IData
    where VM :class, IVM
{
    public static T RunMe(VM hi)
    {
        var vmA = (hi as VM);  //how to force-cast this to the VM type??!!
        return (T)vmA.Data; 
    }
}

class Program
{
    static void Main(string[] args)
    {
        VM_Partial partialData = new VM_Partial();

        var VMClass = new VM_Total(partialData);


        RunVM<DataFull, IVM_Total>.RunMe(VMClass);
        RunVM<DataPartial, IVM_partial>.RunMe(VMClass); //here it throws exception because I can't force cast the IVM to IVM_partial

    }



}

在方法RunVM<DataPartial, IVM_partial>.RunMe(VMClass);,我希望它返回DataPartial对象,我知道它在对象VMClass中,但是我无法完成它。

当我使用InvalidCastException方法时,我会得到一个RunMe,因为参数hi总是VMClass,我永远不会让它表现得像{ {1}}课程。换句话说,我无法将IVM_partial转换为更基本的界面hi

如何将IVM_partial投射到更基本的界面hi?是否有可能,如果没有,为什么不呢?

1 个答案:

答案 0 :(得分:2)

这不是演员问题 - 你希望编译器(或运行时)能够了解演员是一个声明一个新类型的事实Data财产。

RunMe中的这一行:

return (T)vmA.Data;

...将总是使用Data声明的IVM属性,因为这是编译器知道的唯一属性。{1>} 编译该方法。您正在向另一个包含新Data属性的接口进行转换并不重要...转换是关于执行时间检查;它不会更改方法使用的Data属性。

我不清楚你到底想要实现的目标,但我强烈怀疑你需要大幅度改变策略 - 可能是通过在混音中添加另一个泛型类型参数,也许通过更多地使用多态,或者可能更彻底地改变设计。