使 C# 类尽可能接近别名类,以便能够将一个类转换为另一个类

Make a C# class as close as possible to an alias class in order to be able to cast one to the other

提问人:user3078439 提问时间:1/18/2023 最后编辑:user3078439 更新时间:1/18/2023 访问量:69

问:

上下文:我是 C# 的新手,我必须生成 C# 代码(我正在使用 OCaml 完成)。我已经在 SO 上调查了类似的问题,但无济于事,这就是我在这里问的原因。


我有一个定义基本类型的命名空间类型,例如:

public class Address{
            private string _value;
            public Address(string addr){
                _value = addr;
            }
            public static implicit operator string(Address a) => a._value;
            public static implicit operator Address(string s) => new Address(s);
        }

我正在生成 C# 代码,我想在其中定义“别名”类型以与某些外部接口进行交互。 例如,在我的代码生成的一个这样的接口中,我有一个类型,它实际上是 的别名。现在,我以这种方式生成它:ConstructorOperatorTypes.Address

public class Constructor_operator : Types.Address {
public Constructor_operator(Types.Address v) : base(v) {}
public static implicit operator string(Constructor_operator a) => (string) (Types.Address) a;
public static implicit operator Constructor_operator(string a) => (Constructor_operator) (Types.Address) a;
}

但是,一个问题是我经常需要将类的元素转换为类型,这时我遇到了运行时错误,例如,Types.AddressConstructor_operator

public static Constructor_operator _operatorGenerator(){
    return (Constructor_operator)Types.AddressGenerator ();}

调用时,将生成错误:

Unhandled exception. System.InvalidCastException: Unable to cast object of type 'Address' to type 'generatedinterface.Constructor_operator'.
   at generatedinterface.Functions._operatorGenerator() in ~/test_csharp/src/csharp_sdk/generatedinterface_csharp_interface.cs:line 422
   at FactoriTypes.Types.OptionGenerator[T](Func`1 generator) in ~/test_csharp/src/csharp_sdk/factori_types.cs:line 1720
   at generatedinterface.Functions.storageGenerator() in ~/test_csharp/src/csharp_sdk/generatedinterface_csharp_interface.cs:line 1914
   at Program.<<Main>$>g__main|0_0() in ~/test_csharp/src/csharp_sdk/Program.cs:line 11
   at Program.<Main>$(String[] args) in ~/test_csharp/src/csharp_sdk/Program.cs:line 15

我知道我不能这样做的一般原因是你不能将一个类转换为它的子类。但是,(至少在我的意图中)子类实际上与基类相同。无论如何,有谁知道我如何才能成功投进去?AddressConstructorOperator

C# 强制转换 别名

评论

0赞 user3078439 1/18/2023
谢谢!那么构造函数应该是什么样子的呢?
0赞 Selvin 1/18/2023
在运算符 Constructor_operator(string a)' ...实际上会起作用,因为从地址到字符串的 implcit 大小写我的坏......Constructor_operator(Types.Address v) : base(v) {}
1赞 Damien_The_Unbeliever 1/18/2023
C# 不执行结构类型化,如果您来自 OCAML,您将习惯结构类型化。您将无法在 C# 中应用与在 C# 中相同的惯用语。
1赞 Damien_The_Unbeliever 1/18/2023
您可能需要查看 Eric Lippert 关于表示和标识的帖子,以确认 C# 强制转换运算符(可以)的作用。
1赞 Poulpynator 1/18/2023
使用接口并实现它可能是一种解决方案(必须更改执行操作的方式),有关接口用途的详细信息,请参阅接口IAddressConstructor_operator : IAddress

答:

1赞 YungDeiza 1/18/2023 #1

在 C# 中,不能将基对象强制转换为子对象。

以下情况将引发异常:

Constructor_operator con = (Constructor_operator)new Address("address");

这是因为我们试图将类型对象转换为具有比现有信息更多的类型 ()。AddressConstructor_operator

可以将被视为其基类型的对象强制转换为其原始类型。

以下情况不会引发异常:

Address add = new Constructor_operator(new Address("address"));
Constructor_operator con = (Constructor_operator)add;

这是因为它确实是一种类型,并且已经拥有将其视为addConstructor_operatorConstructor_operator

评论

1赞 user3078439 1/18/2023
非常感谢,这似乎解决了我的问题!