我正在尝试将某些C#代码作为F#用于p2p应用程序。.我必须承认我对p2p实现没有完全的了解,我希望它与解决类型问题无关。.所有的p2p库都是用C#实现。

C#实现:

public class TestMessage : Message
{
    public string Text { get; set; }
}


...

var p = new Peer();
p.Subscribe(new Subscription<TestMessage>
{
    Callback = x => Console.WriteLine(x.Text),
});


基本思想是,“ p”对等方现在预订“ TestMessage”类型的消息,然后有一种类似的方法来发布消息。
“订阅”方法的签名为:

void Peer.Subscribe(ISubscription<Message> subscription)


ISubscription接口的定义:

public interface ISubscription<out T> where T : Message
{
    ICachingOptions CachingOptions { get; set; }
    IContact Contact { get; set; }
    string EntitySet { get; set; }
    string Key { get; }
    string Topic { get; }
    Type Type { get; }

    void InvokeCallback(Message message);
    ISerializableSubscription MakeSerializable();
    bool PredicateHolds(Message message);
}


F#实现:

type Xmsg(m:string) =
    inherit Message()
    member this.Text = m

let sub = Subscription<Xmsg>()
sub.Callback <- fun (m: Xmsg) -> System.Console.WriteLine(m.Text)
let p = new Peer()
p.Subscribe sub


最后一行导致以下错误:



The type 'Subscription<Xmsg>' is not compatible with the type 'ISubscription<Message>'




Type constraint mismatch. The type
    Subscription<Xmsg>
is not compatible with type
    ISubscription<Message>
The type 'Subscription<Xmsg>' is not compatible with the type 'ISubscription<Message>'


我尝试用:>和:?>进行上下转换,但是没有成功。

当然,我已经尝试过寻找解决方案,但是,要么没有解决方案,要么我不明白如何将其应用于我的问题...

是否有修复程序?还是我应该为此放弃一个C#库项目(并使用F#中的lib)? :)

最佳答案

正如Ganesh所说,F#不支持协方差,这意味着您不能在F#代码中需要ISubscription<DerivedType>的地方使用ISubscription<BaseType>。但是,对协方差的支持已包含在运行时中,因此您可以通过一组强制转换来解决此问题:

p.Subscribe(box sub :?> ISubscription<_>)


在这里,您一直将sub向上投射到obj,然后向下投射回到ISubscription<Message>,这应该可以工作。

关于c# - 如何解决类型约束不匹配的问题,从C#到F#,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/23018081/

10-12 12:18
查看更多