是否可以实现自定义安全转换(在任意抽象数据结构之间使用“as”)?

Kon*_*ten 4 c# casting .net-core .net-core-3.0

今天,我们有一组类在处理从/到客户端的数据传输时被强制转换为彼此的类型。转换范式在目标的构造函数中实现(即每个对象都知道如何根据输入的类型创建自己)。我们有意拒绝了对象知道如何将自己转换为目标类型(即每个对象都有一组ToTypeXyz()方法)的想法,因为在我们的案例中,出于可维护性的目的,这更有意义。

class ThisType
{
  public ThisType() { ... }
  public ThisType(ThatType input) { ... }
  ...
}

class ThatType
{
  public ThatType() { ... }
  public ThatType(ThisType input) { ... }
  ...
}
Run Code Online (Sandbox Code Playgroud)

我正在考虑移出所有转换逻辑以集中所有工作。一种选择是引入一个带有静态方法的实用程序类(特殊情况是扩展方法以获得更好的编码体验)。

然而,在我们的例子中,如果转换可以通过安全转换进行,即像下面的示例一样使用那就更好了。我认为,它还可以提高性能并降低出现异常的风险。

ThisType input = new ThisType();
...
ThatType target = input as ThatType;
Run Code Online (Sandbox Code Playgroud)

然而,当我在谷歌上搜索“ custom safe cast c# ”时,我没有得到相关结果,可能淹没在标准案例的噪音中。有可能吗?

Joh*_*lay 7

是的,使用隐式/显式转换运算符

class ThatType
{
    public ThatType() { ... }
    public ThatType(ThisType input) { ... }
    ...

    public static implicit operator ThatType(ThisType t) => new ThatType(t);
}
Run Code Online (Sandbox Code Playgroud)

使用上面的隐式版本,这将起作用:

ThisType input = new ThisType();
ThatType target = input;
Run Code Online (Sandbox Code Playgroud)

尽管不幸的是as操作符将不起作用,因为它不尊重用户定义的转换。


Ath*_*ras 6

恐怕你不能这样做:https : //docs.microsoft.com/en-us/dotnet/csharp/language-reference/operators/type-testing-and-cast#as-operator

as 运算符只考虑引用、可为空、装箱和拆箱转换。您不能使用 as 运算符来执行用户定义的转换。为此,请使用强制转换运算符 ()。

由于您的转换不符合这些条件中的任何一个,因此您几乎无法使用转换运算符。