fubogi
fubogi

Reputation: 33

Casting a Type does not work

I have the following classes:

// abstract
abstract class Module
{
    public Options Params;
}

abstract class Options { }

// implementation
class MyModule : Module
{
    public new MyOptions Params = new MyOptions();
}

class MyOptions : Options
{
    public string Param1;
}

and code:

var MyMod = new MyModule();
MyMod.Params.Param1 = "new value"; // ok

// convert
Module Mod = MyMod; // if use MyModule Mod - ok
if (Mod.Params as MyOptions != null)
{
    MessageBox.Show("cast OK"); // not execute
}

Modules can be of different types (I don't know them), but it is always inherited from Module. I need to determine whether the field Params is instance(or implements) MyOptions and get value, if true it. I would be happy with any decisions.

Upvotes: 3

Views: 91

Answers (4)

fubogi
fubogi

Reputation: 33

Also, logical and concise version:

abstract class Module
{
    public Options Params { get; protected set; }
}
abstract class Options { }

class MyModule : Module
{
    public MyOptions MyParams
    {
        get
        {
            if (Params == null) Params = new MyOptions();
            return Params as MyOptions;
        }
    }
}

class MyOptions : Options
{
    public string Param1;
}

using:

var MyMod = new MyModule();
MyMod.MyParams.Param1 = "new value";

// convert
Module Mod = MyMod;
var Params = Mod.Params as MyOptions;

if (Params != null)
{
    MessageBox.Show(Params.Param1);
}

Upvotes: 0

Rotem
Rotem

Reputation: 21947

You are hiding the Options field using the new keyword, thus it would only be accessible when called from MyModule.

There is no connection between Module.Params and MyModule.Params, and even though the runtime knows that Mod is a MyModule, it still gets the value from Module.Params, which is null.

See Knowing When to Use Override and New Keywords

If you want true inheritance, you'll need to use virtual methods (or in this case, virtual properties):

abstract class Module
{
    public abstract Options Params { get; set; }
}

class MyModule : Module
{
    private Options myParams = new MyOptions();
    public override Options Params
    {
        get { return myParams; }
        set { myParams = value; }
    }
}

var MyMod = new MyModule();
(MyMod.Params as MyOptions).Param1 = "new value";

Module Mod = MyMod;
if (Mod.Params as MyOptions != null)
{
    Console.WriteLine("cast OK"); 
}

Upvotes: 2

borkovski
borkovski

Reputation: 978

Mod is considered as Module, so Params is always Options. You should cast Mod first back to MyModule

Upvotes: 0

Kamil Budziewski
Kamil Budziewski

Reputation: 23107

You are looking for is:

if(Mod.Params is MyOptions)
{
}

read about is operator.

It's always better to use is because you don't need to cast and check for null. Try it here

Upvotes: 1

Related Questions