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

Time:01-19

Context: I am new to C# and I have to generate C# code (which I am doing using OCaml). I have investigated similar issues on SO to no avail, which is why I'm asking here.


I have a namespace Types defining elementary types, for example:

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);
        }

I am generating C# code in which I want to define "alias" types to interact with some external interfaces. For instance, in one such interface my code is generating, I have a type ConstructorOperator which is really an alias of Types.Address. For now, I generate it this way:

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;
}

However, one problem is I constantly need to cast elements of the class Types.Address into the type Constructor_operator and that's when I run into runtime errors, for instance,

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

when called, generates the error:

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

I'm aware that the general reason why I can't do this is that you can't cast a class into its subclass. However, (at least in my intentions) the subclass is really the same as the base class. In any case, does anyone have any idea how I can successfully cast Address into ConstructorOperator?

CodePudding user response:

You cannot cast a base object to a child object in C#.

The following will throw an exception:

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

This is because we are trying to cast an Address type object to a type (Constructor_operator) that has more information than is present.

You can cast an object that is being treated as its base type back into its original type.

The following will not throw an exception:

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

This is because add is really a Constructor_operator type and already has all of the information required for us to treat it as a Constructor_operator

  • Related