簡體   English   中英

從C#應用程序調用時,為什么f#中實現的類型與C#類型的行為不一樣?

[英]Why doesn't type implemented in f# behave the same as C# types when called from C# application?

我正在將我的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; }
}

我試圖將其移植到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

問題是,我需要從我的C#應用​​程序中調用這個F#庫。 在使用C#類之前,我可以執行以下操作:

var match= new SoccerMatch(new List<SoccerGame>());
IMatch<IGame> interfaceType = match;

但是當我嘗試對我的F#庫做同樣的事情時:

var match = new SoccerMatch(new List<SoccerGame>());
IMatch<IGame> interfaceType = match;

我收到以下錯誤: 錯誤CS0029無法將類型'FSharp.SoccerMatch'隱式轉換為'FSharp.IMatch'

我認為在我的F#實現中顯然有些問題(顯然),但是什么?

您的F#類型與C#類型的行為不同,因為它與C#類型不同。 C#one將T參數聲明為“out”:

public interface IMatch<out T> where T : IGame

也就是說out裝置類型參數T是協變,而這正是允許從隱式轉換SoccerMatch (這是IMatch<SoccerGame>IMatch<IGame>

但是,據我所知,F#不支持通用接口中的協方差\\逆變。 多年來一直有人建議,但問題仍然存在。 所以你的F#接口類似於這個C#one:

public interface IMatch <T> where T : IGame
{
    IEnumerable<T> Games { get; }
}

哪個會產生相同的編譯時錯誤。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM