.NET等效于Java通配符泛型<?>,具有协方差和反方差?
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了.NET等效于Java通配符泛型<?>,具有协方差和反方差?,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含2716字,纯文字阅读大概需要4分钟。
内容图文
![.NET等效于Java通配符泛型<?>,具有协方差和反方差?](/upload/InfoBanner/zyjiaocheng/816/8f179d1801d14100987a2da79228f238.jpg)
我试图将一些使用(有界)通配符泛型的Java代码转换为C#.
我的问题是,Java似乎允许泛型类型在与通配符一起使用时既是协变的又是逆变的.例如:
Java的:
interface IInterf { }
class Impl implements IInterf { }
interface IGeneric1<T extends Impl> {
void method1(IGeneric2<?> val);
void method1WithParam(T val);
}
interface IGeneric2<T extends Impl> {
void method2(IGeneric1<?> val);
}
abstract class Generic<T extends Impl> implements IGeneric1<T>, IGeneric2<T> {
public void method1(IGeneric2<?> val2) {
val2.method2(this);
}
}
…作品.
C#等价(?)
interface IInterf { }
class Impl : IInterf { }
interface IGeneric1<T> where T:Impl {
//Java was:
//void method1(IGeneric2<?> val2);
void method1(IGeneric2<Impl> val);
void method1WithParam(T to);
}
interface IGeneric2<T>where T:Impl {
void method2(IGeneric1<Impl> val);
}
abstract class Generic<T> : IGeneric1<T>, IGeneric2<T> where T : Impl
{
//Java was:
//public void method1(IGeneric2<?> val2) {
public void method1(IGeneric2<Impl> val2)
{
val2.method2(this); //'this': Argument type 'Generic<T>' is not
//assignable to parameter type 'IGeneric1<Impl>'
}
public abstract void method1WithParam(T to);
public abstract void method2(IGeneric1<Impl> val);
}
…无法编译 – 请参阅注释中的错误.这是可以预期的,因为IGeneric的通用参数没有为协方差标记为’out’.
如果我改变了这个:
interface IGeneric1<T> where T:Impl {
对此
interface IGeneric1<out T> where T:Impl
错误消失了,但是另一个出现了,因为声明了在同一个接口中采用泛型参数的方法:
interface IGeneric1<T> where T:Impl {
void method1WithParam(T val); //Parameter must be input-safe.
//Invalid variance: The type parameter 'T' must be
//contravariantly valid on 'IGeneric1<out T>'.
建议?
[另请参阅follow-up question更难的情况]
解决方法:
您需要将Java通配符泛型方法转换为本身通用??的C#方法.例如,这个:
interface IGeneric2<T extends Impl> {
void method2(IGeneric1<?> val);
}
应该翻译成
interface IGeneric2<T>where T:Impl {
void method2<U>(IGeneric1<U> val) where U:Impl;
}
有必要重复由IGeneric1< T>指定的T的类型约束.作为U的类型约束.
其原因在于,在Java版本中,对于method1和method2的参数的类型参数存在隐式约束:如果参数必须是某种IGeneric1< X>.那么X显然必须是一个Impl,否则就不可能为该类型实现IGeneric1.
在C#中,约束必须是显式的,所以你重复IGeneric1< T>和IGeneric2< T>需要T.
所以等效的代码是:
interface IInterf { }
class Impl : IInterf { }
interface IGeneric1<T> where T:Impl {
void method1<U>(IGeneric2<U> val) where U:Impl;
void method1WithParam(T to);
}
interface IGeneric2<T>where T:Impl {
void method2<U>(IGeneric1<U> val) where U:Impl;
}
abstract class Generic<T> : IGeneric1<T>, IGeneric2<T> where T : Impl
{
public void method1<U>(IGeneric2<U> val2) where U:Impl
{
val2.method2(this);
}
public abstract void method1WithParam(T to);
public abstract void method2<U>(IGeneric1<U> val) where U:Impl;
}
内容总结
以上是互联网集市为您收集整理的.NET等效于Java通配符泛型<?>,具有协方差和反方差?全部内容,希望文章能够帮你解决.NET等效于Java通配符泛型<?>,具有协方差和反方差?所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。