[英]How to help type inference using C# classes in F#
使用用 C# 編寫的充氣城堡 v.1.0.1 我遇到了類型推斷問題。 C#代碼有很多繼承和接口使用。
// Definitions
public interface IParameters<out TAlg> where TAlg: Algorithm { ... }
public abstract class SignatureParameters<TParam, TAlg, DAlg> : Parameters<TAlg>, ISignatureParameters<TParam, TAlg, DAlg>
where TParam : IParameters<TAlg>
where TAlg : Algorithm
where DAlg : DigestAlgorithm {}
// SignatureFactory interface
public interface ISignatureFactoryService
{
ISignatureFactory<A> CreateSignatureFactory<A>(A algorithmDetails) where A : IParameters<Algorithm>;
}
// SignatureFactory creation
public class SomeClass : ISignatureFactoryService
{
public ISignatureFactory<A> CreateSignatureFactory<A>(A algorithmDetails) where A : IParameters<Algorithm>
{
...
return (ISignatureFactory<A>)new SignatureFactory<Fips.FipsEC.SignatureParameters>(algorithmDetails as Fips.FipsEC.SignatureParameters, new Fips.FipsEC.SignerProvider(algorithmDetails as Fips.FipsEC.SignatureParameters, privateKey));
}
}
現在,當我使用 F# 中的庫時,編譯器會顯示問題,因為它無法解析/映射IParameters<Algorithm>
到FipsEC.SignatureParameters
// usage F#
let vKey = ... // is AsymmetricECPrivateKey
let signatureFactoryProvider = CryptoServicesRegistrar.CreateService(vKey, new SecureRandom())
let sigParams = FipsEC.Dsa.WithDigest(FipsShs.Sha256)
// sigParam will be of type FipsEC.SignatureParameters
let sigFactry = signatureFactoryProvider.CreateSignatureFactory(sigParams)
// error, FS0001: The type 'FipsEC.SignatureParameters' is not compatible with the type 'IParameters<Algorithm>'
FipsEC.SignatureParameters
定義為
public class SignatureParameters: SignatureParameters<SignatureParameters, FipsAlgorithm, FipsDigestAlgorithm>
{
internal SignatureParameters(FipsAlgorithm algorithm, FipsDigestAlgorithm digestAlgorithm): base(algorithm, digestAlgorithm)
{
}
internal override SignatureParameters CreateParameter(FipsAlgorithm algorithm, FipsDigestAlgorithm digestAlgorithm)
{
return new SignatureParameters (algorithm, digestAlgorithm);
}
}
我試圖定義正確的類型,但顯然這沒有做任何事情
let sigParams = IParameters<Algorithm> = FipsEC.Dsa.WithDigest(FipsShs.Sha256)
// error FS0001: this expression was expected to have type 'IParameters<Algorithm>' but here has type 'FipsEC.SignatureParameters' which itself is again Parameters<TAlg>, ISignatureParameters<TParam, TAlg, DAlg> (see above), so it should work...
現在的問題是,我如何幫助編譯器? 我試過投它,但沒有運氣。
F# 中沒有隱式轉換( obj
除外),因此您必須顯式轉換為接口,或使用靈活類型:
1. 顯式轉換:
upcast
運算符:let sigParams : IParameters<Algorithm> = upcast FipsEC.Dsa.WithDigest(FipsShs.Sha256)
:>
) 運算符:let sigParams = FipsEC.Dsa.WithDigest(FipsShs.Sha256) :> IParameters<Algorithm>
2、靈活的類型(注意接口類型前的#
號):
let sigParams : #IParameters<Algorithm> = FipsEC.Dsa.WithDigest(FipsShs.Sha256)
第二個在函數定義中特別有用:
let doSomethingWithParameters<'a> (params: #IParameters<'a>) = // some action here
// ...
// usage of the defined above function:
FipsEC.Dsa.WithDigest(FipsShs.Sha256)
|> doSomethingWithParameters
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.