我正在将我的C#代码移植到F#库中.我的C#库中有以下接口/类:
public interface IMatch<out T> where T : IGame
{
IEnumerable<T> Games { get; }
}
public interface IGame
{
string Name { get; }
}
public class SoccerMatch : IMatch<SoccerGame>
{
public SoccerMatch(IEnumerable<SoccerGame> games)
{
Games = games;
}
public IEnumerable<SoccerGame> Games { get; }
}
public class SoccerGame : IGame
{
public SoccerGame(string name)
{
Name = name;
}
public string Name { get; }
}
Run Code Online (Sandbox Code Playgroud)
我试图将其移植到F#,这就是我想出来的:
type IGame =
abstract member Name: string with get
type IMatch<'T when 'T :> IGame> =
abstract member Games: IEnumerable<'T> with get
type SoccerGame =
{Name: string}
interface IGame with
member this.Name with get() = this.Name
type SoccerMatch =
{ Games: IEnumerable<SoccerGame>}
interface IMatch<SoccerGame> with
member this.Games: IEnumerable<SoccerGame> = this.Games
Run Code Online (Sandbox Code Playgroud)
问题是,我需要从我的C#应用程序中调用这个F#库.在使用C#类之前,我可以执行以下操作:
var match= new SoccerMatch(new List<SoccerGame>());
IMatch<IGame> interfaceType = match;
Run Code Online (Sandbox Code Playgroud)
但是当我尝试对我的F#库做同样的事情时:
var match = new SoccerMatch(new List<SoccerGame>());
IMatch<IGame> interfaceType = match;
Run Code Online (Sandbox Code Playgroud)
我收到以下错误:错误CS0029无法将类型'FSharp.SoccerMatch'隐式转换为'FSharp.IMatch'
我认为在我的F#实现中显然有些问题(显然),但是什么?
您的F#类型与C#类型的行为不同,因为它与C#类型不同.C#one的T参数声明为"out":
public interface IMatch<out T> where T : IGame
Run Code Online (Sandbox Code Playgroud)
这out意味着类型参数T是协变的,这正是允许从SoccerMatch(即IMatch<SoccerGame>)的隐式转换IMatch<IGame>.
但是,据我所知,F#不支持通用接口中的协方差\逆变.多年来一直有人建议,但问题仍然存在.所以你的F#接口类似于这个C#one:
public interface IMatch <T> where T : IGame
{
IEnumerable<T> Games { get; }
}
Run Code Online (Sandbox Code Playgroud)
哪个会产生相同的编译时错误.
| 归档时间: |
|
| 查看次数: |
100 次 |
| 最近记录: |