我正在尝试将某些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/