问题
I'm trying to implement some C# code as F# for a p2p application.. I must admit I don't have full understanding of the p2p implementation and I hope it is irrelevant for fixing the type problem.. All of the p2p library is implemented in C#.
The C# implementation:
public class TestMessage : Message
{
public string Text { get; set; }
}
...
var p = new Peer();
p.Subscribe(new Subscription<TestMessage>
{
Callback = x => Console.WriteLine(x.Text),
});
The basic idea is that the 'p' peer now subscribes to messages of the type 'TestMessage', and then there is a similar method for publishing messages.. The signature for the 'Subscribe' method is:
void Peer.Subscribe(ISubscription<Message> subscription)
The definition of the ISubscription interface:
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);
}
The F# implementation:
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 last line results in following errors:
The type 'Subscription<Xmsg>' is not compatible with the type 'ISubscription<Message>'
and
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>'
I have tried messing around with :> and :?> for upcasting and downcasting, -but with no success..
Of course I have tried to search for a solution, however, either there are none or I don't understand how to apply them for my problem...
Is there a fix?, or should I just give up and make a C# library project for it (and use that lib from F#)? :)
回答1:
As Ganesh says, F# doesn't support covariance, which means that you can't use an ISubscription<DerivedType>
where an ISubscription<BaseType>
is needed in F# code. However, support for covariance is baked into the runtime, so you can probably get around this with a set of casts:
p.Subscribe(box sub :?> ISubscription<_>)
Here you're upcasting sub
all the way to an obj
and then downcasting back to an ISubscription<Message>
, which ought to work.
来源:https://stackoverflow.com/questions/23018081/how-to-solve-type-constraint-mismatch-c-sharp-to-f