使用具有多个通用约束的泛型时出错

时间:2015-03-16 09:59:08

标签: c# generics

我继承了一个由我无法控制的基本框架组成的应用程序。现在有些类已经改变了,我必须更新它的用法。

基本框架严重依赖于泛型。现在我在使用它们时遇到了一些问题。此代码以简化的方式表示问题:

class MainClass<T, U, V> 
    where T : ClassA<U, V> , new()
    where U : ClassB<V>, new() 
    where V : ClassC
{
    void AddSomething()
    {
        U myU = new U();
        myU.Data = new ClassCImpl();

        // "Cannot convert source type ClassCImpl to target type V"
    }

    void AddSomething2()
    {
        List<U> val = new List<U>();

        ClassB<ClassC> myClBC = new ClassB<ClassC>();
        myClBC.Data = new ClassCImpl();

        val.Add(myClBC);

        // "Argument type ClassB<ClassC> is not assignable to U"
    }
}

框架类看起来像这样:

class ClassA<T, U>
    where T : ClassB<U> 
    where U : ClassC
{ }

class ClassB<T> where T : ClassC
{
    public virtual T Data {get; set;}
}

abstract class ClassC { }

class ClassCImpl : ClassC { }

代码目前在类AddSomething的方法MainClass中使用。此代码抛出错误“无法将源类型ClassEImpl转换为目标类型V”。我认为这可能与ClassCImpl不是类型ClassC的泛型约束中的确切类型有关。所以我尝试使用AddSomething2,因为我不需要它在那里通用。但是,这会引发错误“参数类型ClassB不能分配给U”,但我认为ClassB<ClassC>正好是U

现在我想知道,我逻辑中的错误在哪里?

1 个答案:

答案 0 :(得分:0)

您认为ClassCImplT的{​​{1}}兼容。

假设我有:

ClassB<T>

这将尝试将public class OtherClassC : ClassC {} ... MainClass mc = new MainClass<ClassB<OtherClassC>, OtherClassC>(); mc.AddSomething(); 值设置为ClassCImpl类型的属性。那不行。

同样,您的OtherClassC方法会尝试将AddSomething2添加到ClassB<ClassC> - 再次,这是无效的。

您想要实现的目标并不完全清楚,但是当您开始尝试在List<ClassB<OtherClassC>>方法中使用特定的具体类型时,您可能会遇到问题。您应该尝试使用这些代码 less 泛型 - 除了其他任何东西之外,这样可以更容易找出错误。