F#结构判别联合与C#的互操作:转换到特定情况
具有一个类似于F#结构判别联合与C#的互操作:转换到特定情况,f#,F#,具有一个类似于 type Result<'T,'TError> = | Ok of 'T | Error of 'TError 类型结果= |当然可以 |“恐怖”的错误 您可以强制转换到C#中的一种情况,比如var error=(Result.error)Result,但它不会使用等效的结构判别联合编译 在C#互操作场景中,如何转换为结构判别式联合的特定情况?或者,在CLR类型中如何表示结构判别联合事例?您可以使用Sharplab.io查看此类型的: public
type Result<'T,'TError> =
| Ok of 'T
| Error of 'TError
类型结果=
|当然可以
|“恐怖”的错误
您可以强制转换到C#中的一种情况,比如var error=(Result.error)Result
,但它不会使用等效的结构判别联合编译
在C#互操作场景中,如何转换为结构判别式联合的特定情况?或者,在CLR类型中如何表示结构判别联合事例?您可以使用Sharplab.io查看此类型的:
public abstract class Result<T, TError> : IEquatable<Result<T, TError>>, IStructuralEquatable, IComparable<Result<T, TError>>, IComparable, IStructuralComparable
{
public static class Tags
{
public const int Ok = 0;
public const int Error = 1;
}
public class Ok : Result<T, TError>
{
internal readonly T item;
public T Item =>item;
internal Ok(T item) { this.item = item;}
}
public class Error : Result<T, TError>
{
internal readonly TError item;
public TError Item => item;
internal Error(TError item) { this.item = item; }
}
...
public int Tag => (this is Error) ? 1 : 0;
public bool IsOk=> this is Ok;
public bool IsError =>this is Error;
}
不幸的是,还不可能为此编写一个详尽的开关表达式。使用相同的模式(带有具体案例的基本枚举类),因此这可能在C#9中得到修复
在C#8中,可以使用属性模式提取包含的值(结果或错误):
更新-结构
我错过了struct
部分。在这种情况下-一个包含所有属性的平面struct
:
public struct Result<T, TError>
{
public static class Tags
{
public const int Ok = 0;
public const int Error = 1;
}
public int Tag {get;}
public bool IsOk =>Tag == 0;
public bool IsError=>Tag == 1;
public T ok {get;}
public TError error {get;}
public static Result<T, TError> NewOk(T _ok)
{
return new Result<T, TError>(_ok, 0, false);
}
public static Result<T, TError> NewError(TError _error)
{
return new Result<T, TError>(_error, 1, 0);
}
internal Result(T _ok, int _tag, bool P_2)
{
this.ok = _ok;
this.Tag = _tag;
this.error=default;
}
internal Result(TError _error, int _tag, byte P_2)
{
this.error = _error;
this.Tag = _tag;
this.ok=default;
}
}
另一方面,这不是最直观的表达。当C#9 DU也出现时,它可能会破裂。C#9可以使用原始模式,为基类及其成员使用默认接口成员。F#编译器必须更改以使用新语法 您可以使用Sharplab.io查看此类型:
public abstract class Result<T, TError> : IEquatable<Result<T, TError>>, IStructuralEquatable, IComparable<Result<T, TError>>, IComparable, IStructuralComparable
{
public static class Tags
{
public const int Ok = 0;
public const int Error = 1;
}
public class Ok : Result<T, TError>
{
internal readonly T item;
public T Item =>item;
internal Ok(T item) { this.item = item;}
}
public class Error : Result<T, TError>
{
internal readonly TError item;
public TError Item => item;
internal Error(TError item) { this.item = item; }
}
...
public int Tag => (this is Error) ? 1 : 0;
public bool IsOk=> this is Ok;
public bool IsError =>this is Error;
}
不幸的是,还不可能为此编写一个详尽的开关表达式。使用相同的模式(带有具体案例的基本枚举类),因此这可能在C#9中得到修复
在C#8中,可以使用属性模式提取包含的值(结果或错误):
更新-结构
我错过了struct
部分。在这种情况下-一个包含所有属性的平面struct
:
public struct Result<T, TError>
{
public static class Tags
{
public const int Ok = 0;
public const int Error = 1;
}
public int Tag {get;}
public bool IsOk =>Tag == 0;
public bool IsError=>Tag == 1;
public T ok {get;}
public TError error {get;}
public static Result<T, TError> NewOk(T _ok)
{
return new Result<T, TError>(_ok, 0, false);
}
public static Result<T, TError> NewError(TError _error)
{
return new Result<T, TError>(_error, 1, 0);
}
internal Result(T _ok, int _tag, bool P_2)
{
this.ok = _ok;
this.Tag = _tag;
this.error=default;
}
internal Result(TError _error, int _tag, byte P_2)
{
this.error = _error;
this.Tag = _tag;
this.ok=default;
}
}
另一方面,这不是最直观的表达。当C#9 DU也出现时,它可能会破裂。C#9可以使用原始模式,为基类及其成员使用默认接口成员。F#编译器必须更改以使用新语法 首先,没有等效的结构DU。编译器将强制您在切换到结构DU时为字段命名
[<Struct>]
type Result<'T,'TError> =
| Ok of 'T
| Error of 'TError
;;
type Result<'T,'TError> =
-----^^^^^^
error FS3204: If a union type has more than one case and is a struct,
then all fields within the union type must be given unique names.
首先,没有等效的结构DU。编译器将强制您在切换到结构DU时为字段命名
[<Struct>]
type Result<'T,'TError> =
| Ok of 'T
| Error of 'TError
;;
type Result<'T,'TError> =
-----^^^^^^
error FS3204: If a union type has more than one case and is a struct,
then all fields within the union type must be given unique names.
返回一个不同的类-base
Result
类,该类包含两个内部
具体类。是的,当它不是struct DU时。但看起来他已经知道了。错过了struct
和。。。哎呀。我知道当C#9问世时会出现一些互操作问题。代码完全不同。仍然可以使用模式匹配,只是与自然模式非常不同。让我们希望他们之前修复它!这两种结果完全不同,因此如果不修改F#编译器或在C#9中生成不同的代码,这将是不容易的。我看不出它会返回一个不同的类,即带有两个内部具体类的baseResult
类。但看起来他已经知道了。错过了struct
和。。。哎呀。我知道当C#9问世时会出现一些互操作问题。代码完全不同。仍然可以使用模式匹配,只是与自然模式非常不同。让我们希望他们之前修复它!这两种结果完全不同,因此如果不修改F#编译器或在C#9中生成不同的代码,这将是不容易的。我不认为使用struct DUs会发生这种情况,你可以在C#8中编写一个穷举开关表达式,但感觉不自然。使用struct DUs,你可以在C#8中编写一个穷举开关表达式,但感觉不自然。
[<Struct>]
type Result<'T,'TError> =
| Ok of 'T
| Error of 'TError
;;
type Result<'T,'TError> =
-----^^^^^^
error FS3204: If a union type has more than one case and is a struct,
then all fields within the union type must be given unique names.
[<Struct>]
type Result<'T,'TError> =
| Ok of ok: 'T
| Error of error: 'TError
var error = result.error;