使用具有多个泛型约束的泛型时出错
Error when using generics with multiple generic constrains
我继承了一个由我无法控制的基本框架组成的应用程序。现在一些 classes 在那里发生了变化,我必须更新我们对它的使用。
基本框架严重依赖泛型。现在我在使用它们时遇到了一定的问题。此代码以简化的方式表示问题:
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是这样的:
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 { }
该代码目前在 class MainClass
中的方法 AddSomething
中使用。此代码抛出错误 "Cannot convert source type ClassEImpl to target type V"。我认为这可能与 ClassCImpl
不是类型 ClassC
的泛型约束中的确切类型有关。所以我尝试使用 AddSomething2
,因为我在那里不一定需要它。但是,这会引发错误 "Argument type ClassB is not assignable to U",但我认为 ClassB<ClassC>
正是 U
。
现在我想知道,我的逻辑哪里出错了?
您假设 ClassCImpl
与 ClassB<T>
的 T
兼容。
假设我有:
public class OtherClassC : ClassC {}
...
MainClass mc = new MainClass<ClassB<OtherClassC>, OtherClassC>();
mc.AddSomething();
这将尝试将 ClassCImpl
值设置为类型 OtherClassC
的 属性。那是行不通的。
同样,您的 AddSomething2
方法会尝试将 ClassB<ClassC>
添加到 List<ClassB<OtherClassC>>
- 同样,这是无效的。
尚不完全清楚您要实现的目标,但是当您开始尝试在 AddSomething
方法中使用特定的具体类型时,您可能会遇到问题。您可能应该尝试使某些代码 less 通用 - 除了其他任何事情,这将使找出问题所在变得更容易。
我继承了一个由我无法控制的基本框架组成的应用程序。现在一些 classes 在那里发生了变化,我必须更新我们对它的使用。
基本框架严重依赖泛型。现在我在使用它们时遇到了一定的问题。此代码以简化的方式表示问题:
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是这样的:
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 { }
该代码目前在 class MainClass
中的方法 AddSomething
中使用。此代码抛出错误 "Cannot convert source type ClassEImpl to target type V"。我认为这可能与 ClassCImpl
不是类型 ClassC
的泛型约束中的确切类型有关。所以我尝试使用 AddSomething2
,因为我在那里不一定需要它。但是,这会引发错误 "Argument type ClassB is not assignable to U",但我认为 ClassB<ClassC>
正是 U
。
现在我想知道,我的逻辑哪里出错了?
您假设 ClassCImpl
与 ClassB<T>
的 T
兼容。
假设我有:
public class OtherClassC : ClassC {}
...
MainClass mc = new MainClass<ClassB<OtherClassC>, OtherClassC>();
mc.AddSomething();
这将尝试将 ClassCImpl
值设置为类型 OtherClassC
的 属性。那是行不通的。
同样,您的 AddSomething2
方法会尝试将 ClassB<ClassC>
添加到 List<ClassB<OtherClassC>>
- 同样,这是无效的。
尚不完全清楚您要实现的目标,但是当您开始尝试在 AddSomething
方法中使用特定的具体类型时,您可能会遇到问题。您可能应该尝试使某些代码 less 通用 - 除了其他任何事情,这将使找出问题所在变得更容易。