[英]F# 4.5.0.0: error FS0193: This expression is a function value, i.e. is missing arguments. Its type is Exception -> 'a
我正在將 class 從 C# 調整為 F#,在代碼中我有一個引發異常的方法,並且此方法需要具有通用返回。 When in C# to F# it works perfectly, but from F# to F# a compilation error happens: FS0193 This expression is a function value, ie is missing arguments. 它的類型是 Exception -> 'a.
member this.Throw() =
try
raise ...
with
| exc -> ...
Unchecked.defaultof<'T> // <- Error
如果需要完整類型,我會編輯問題。
好的,格斯。 編輯:我的目標是將 FSharp.Core 版本 4.5.0.0 移植到 .NET 4.0。 為了實現我的目標,我在 F# 中重寫了 Theraot.Core 的部分內容,因為 FSharp.Core 不“接受”第三方庫: https://github.com/theraot/Theraot/issues/121 。
C# 中的 Class: https://github.com/theraot/Theraot/blob/master/Framework.Core/System/Runtime/ExceptionServices/ExceptionDispatchInfo
輸入 F#:
namespace System.Runtime.ExceptionServices
open System
open Microsoft.FSharp.Core
open System.Text
open System.Reflection
/// <summary>
/// The ExceptionDispatchInfo object stores the stack trace information and Watson information that the exception
/// contains at the point where it is captured. The exception can be thrown at another time and possibly on another
/// thread by calling the ExceptionDispatchInfo.Throw method. The exception is thrown as if it had flowed from the
/// point where it was captured to the point where the Throw method is called.
/// </summary>
[<Sealed;AllowNullLiteral>]
type ExceptionDispatchInfo private(exc : exn) =
let _stackTrace = exc.StackTrace
static member val private _remoteStackTraceString : FieldInfo = null with get, set
/// <summary>
/// Gets the exception that is represented by the current instance.
/// </summary>
member val SourceException = exc with get
/// <summary>
/// Creates an ExceptionDispatchInfo object that represents the specified exception at the current point in code.
/// </summary>
/// <param name="source">The exception whose state is captured, and which is represented by the returned object.</param>
/// <returns>An object that represents the specified exception at the current point in code. </returns>
static member Capture(source : exn) =
if source = null
then raise(new ArgumentNullException "source")
new ExceptionDispatchInfo(source)
/// <summary>
/// Throws the exception that is represented by the current ExceptionDispatchInfo object, after restoring the state
/// that was saved when the exception was captured.
/// </summary>
member this.Throw() =
try
raise this.SourceException
with
| exc ->
let newStackTrace = _stackTrace + ExceptionDispatchInfo.BuildStackTrace(Environment.StackTrace)
ExceptionDispatchInfo.SetStackTrace(this.SourceException, newStackTrace)
raise
static member private BuildStackTrace(trace : string) =
let items = trace.Split([|Environment.NewLine|], StringSplitOptions.RemoveEmptyEntries)
let newStackTrace = new StringBuilder()
let mutable found = false
let mutable contains = false
for item in items do
if not contains then
if item.Contains ":" then
if item.Contains "System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()"
then contains <- true
else
if found
then newStackTrace.Append Environment.NewLine |> ignore
found <- true
newStackTrace.Append item |> ignore
elif found
then contains <- true
newStackTrace.ToString()
static member private GetFieldInfo() =
if ExceptionDispatchInfo._remoteStackTraceString = null then
// ---
// Code by Miguel de Icaza
let mutable remoteStackTraceString = typeof<Exception>.GetField("_remoteStackTraceString", BindingFlags.Instance ||| BindingFlags.NonPublic)
if remoteStackTraceString = null then remoteStackTraceString <- typeof<Exception>.GetField("remote_stack_trace", BindingFlags.Instance ||| BindingFlags.NonPublic)
ExceptionDispatchInfo._remoteStackTraceString <- remoteStackTraceString
ExceptionDispatchInfo._remoteStackTraceString
static member private SetStackTrace(exc : exn, value) =
let remoteStackTraceString = ExceptionDispatchInfo.GetFieldInfo()
remoteStackTraceString.SetValue(exc, value)
發生錯誤的地方: https://github.com/fsharp/fsharp/blob/master/src/fsharp/FSharp.Core/async.fs#L65
如果 Gus 需要更多信息或截圖,請發表評論。
問題是你翻譯的C# throw;
就像raise
- 但這是不正確的。 如果要重新拋出當前異常,需要使用reraise reraise()
function:
member this.Throw() =
try
raise this.SourceException
with
| exc ->
let newStackTrace = _stackTrace +
ExceptionDispatchInfo.BuildStackTrace(Environment.StackTrace)
ExceptionDispatchInfo.SetStackTrace(this.SourceException, newStackTrace)
reraise()
在您的原始代碼中發生的情況是Throw()
方法不返回值,而是返回raise
function 的值,這是一個引發給定異常的 function。 這在語法上是有效的,但類型與您預期的不同。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.