如何使用泛型类型类转换为正式实现?

时间:2018-08-27 09:35:58

标签: c# .net generics casting upcasting

当我们尝试从通用类型类转换为正式实现时,会产生转换错误。

在下面的代码中,您可以看到我有一个FormalClass,它是GenericTypeClass的实现。当我尝试从GenericTypeClass转换为FormalClass时,出现此错误:

[System.InvalidCastException:无法将类型'GenericTypeClass`1 [TestType]'的对象强制转换为类型'FormalClass'。]

我知道这是行不通的,但是如果您需要进行升级,什么是最好的解决方法?自动映射器? Json序列化?其他吗?

下面是一个dotnetfiddle(https://dotnetfiddle.net/LLg0vp)示例:

using System;

public class Program
{
    public static void Main()
    {
        var a = new GenericTypeClass<TestType>();

        var b = a as FormalClass;
        if (b == null)
            Console.WriteLine("'a as Formal' Is NULL");

        try
        {
            var c = (FormalClass)a;
        }
        catch (Exception ex)
        {
            Console.WriteLine("'(FormalClass)a' gives this error: " + ex.Message);
        }
    }
}

public class FormalClass : GenericTypeClass<TestType>
{
}

public class GenericTypeClass<T>
    where T : class, IType
{
}

public class TestType : IType
{
}

public interface IType
{
}

2 个答案:

答案 0 :(得分:1)

您无法通过继承来完成此任务。创建类型为GenericTypeClass<TestType>的对象后,它就永远无法成为FormalClass

选项:

  1. 研究创建FormalClass而不是 GenericTypeClass<TestType>
    • 这可能是简单的也可能是复杂的,具体取决于代码的流程。
  2. 创建一个新的FormalClass并使用自动映射器将属性值复制到其中
    • 更改为新的FormalClass对象中的属性不会对原始Generic对象产生影响。
  3. 与其使FormalClass继承自GenericTypeClass<TestType>', make it a wrapper for a GenericTypeClass'并在构造函数中传递`GenericTypeClass',反而。
    • 添加到Generic类的任何新属性都必须添加到FormalClass

我提供了包装方法的代码示例。


using System;

public class Program
{
    public static void Main()
    {
        var a = new GenericTypeClass<TestType>();
        var b = new FormalClass(a);
        a.Name = "NameA";
        b.Name = "NameB";
        Console.WriteLine(a.Name);
        Console.WriteLine(b.Name);
    }
}

public class FormalClass
{
    GenericTypeClass<TestType> _inner;
    public FormalClass(GenericTypeClass<TestType> parameter)
    {
        _inner = parameter;
    }

    public string Name
    {
        get
        {
            return _inner.Name;
        }

        set
        {
            _inner.Name = value;
        }
    }
}

public class GenericTypeClass<T>
    where T : class, IType
{
    public string Name
    {
        get;
        set;
    }
}

public class TestType : IType
{
}

public interface IType
{
}

答案 1 :(得分:0)

您的示例可以简化如下(请注意,泛型在这里没有任何作用):

void Main()
{
    var a = new BaseClass();

    var b = a as DerivedClass;
    if (b == null)
        Console.WriteLine("'a as Derived' Is NULL");
}


public class BaseClass
{
}

public class DerivedClass : BaseClass
{
}

...当然,这永远行不通。派生类可以强制转换回基类,但反之亦然。