簡體   English   中英

如何在 F# 中使用 C# 類幫助類型推斷

[英]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.

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