Zuriki
Zuriki

Reputation: 11

C# - Change argument type of override method

I have an inherited class and I am trying to change the event method's argument type to a different type that is also an inherited class.

The original classes:

public class Alpha {
    protected virtual void OnSpecialEvent( AlphaArgs e );
}

public class AlphaArgs {
    public AlphaArgs ( int a, object b );

    public int A { get; }
    public object B { get; }
}

My inheriting classes:

public class Beta : Alpha {
    protected override void OnSpecialEvent ( BetaArgs e )
    {
        /* Do Stuff */
    }
}

public class BetaArgs : AlphaArgs {
    public BetaArgs (int a, object b, string c) : base (a, b)
    {
        /* Do Stuff */
    }

    public string C { get; }
}

But I end up with the error:

CS0115  'Beta.OnSpecialEvent(BetaArgs)': no suitable method found to override

If I use AlphaArgs I don't have any 'problem' but I lose the extra parameter than I want to add.

Is there something obvious I'm missing, I don't even know what I'm looking for...

Upvotes: 0

Views: 2032

Answers (4)

Ali Nazem
Ali Nazem

Reputation: 116

You can achieve this by changing OnSpecialEvent() so that it accepts a generic type instead of AlphaArgs:

public class Alpha<T>
{
    protected virtual void OnSpecialEvent(T e)
    {
        //do stuff
    }
}

To make sure the generic type T is restricted to AlphaArgs or any other class inheriting from it (BetaArgs in this case), add a generic type constraint:

public class Alpha<T> where T : AlphaArgs
{
    protected virtual void OnSpecialEvent(T e)
    {
        //do stuff
    }
}

Then by defining Beta as below you can specify the type of argument to be passed to Beta.OnSpecialEvent.

public class Beta : Alpha<BetaArgs>
{
    protected override void OnSpecialEvent(BetaArgs e)
    {
        //do stuff
    }
}

(In fact Visual Studio AutoComplete will exactly suggest the same signature for Beta.OnSpecialEvent) Visual Studio AutoComplete on overridden function with a generic argument

The entire code would look like:

public class AlphaArgs
{
    public AlphaArgs(int a, object b)
    {
        //do stuff
    }

    public int A { get; }
    public object B { get; }
}

public class BetaArgs : AlphaArgs
{
    public BetaArgs(int a, object b, string c) : base(a, b)
    {
        /* Do Stuff */
    }

    public string C { get; }
}

public class Alpha<T> where T : AlphaArgs
{
    protected virtual void OnSpecialEvent(T e)
    {
        //do stuff
    }
}

public class Beta : Alpha<BetaArgs>
{
    protected override void OnSpecialEvent(BetaArgs e)
    {
        //do stuff
    }
}

Upvotes: 1

Ricardo Fran&#231;a
Ricardo Fran&#231;a

Reputation: 3003

You can use generics! Take a look:

public interface IBase<T>
    {
        void OnSpecialEvent(T e);
    }

    public class Alpha : IBase<AlphaArgs>
    {
        public void OnSpecialEvent(AlphaArgs e)
        {
            throw new NotImplementedException();
        }
    }

    public class Beta : IBase<BetaArgs>
    {
        public void OnSpecialEvent(BetaArgs e)
        {
            throw new NotImplementedException();
        }
    }

    public class AlphaArgs
    {
        public int A { get; }
        public object B { get; }
    }

    public class BetaArgs
    {
        public string C { get; }
    }

Upvotes: 3

Gediminas Masaitis
Gediminas Masaitis

Reputation: 3212

You can't do that. If it was possible, consider this:

Beta beta = new Beta();
Alpha stillBeta = (Alpha)beta; // Here the compile-time type is Alpha,
                               // but the run-time type is Beta.
AlphaArgs alphaArgs = new AlphaArgs(1,2);
stillBeta.OnSpecialEvent(alphaArgs); // What should happen here?

Now your Beta instance, which is expecting BetaArgs, is instead getting a less-derived instance of AlphaArgs. That can't work - it breaks polymorphism.

Upvotes: 0

Khizar Iqbal
Khizar Iqbal

Reputation: 495

whenever you want to override a method of base class, you must have to override it with the same signature as in the base class. and also you are not overriding the method but overloading. you can however do the following:

protected override void OnSpecialEvent(AlphaArgs e)
{
    BetaArgs be = e as BetaArgs;
    if(be != null)
    {
        /* Do Stuff */
    }
    base.OnSpecialEvent(e)
}

or if you prefer, you can create an overload OnSpecialEvent.

protected void OnSpecialEvent(BetaArgs e)
{
    BetaArgs be = e as BetaArgs;
    if(be != null)
    {
        /* Do Stuff */
    }
}

for more info, you can read this here. https://stackoverflow.com/a/27547235/1926877

Hope this will help you.

Upvotes: 0

Related Questions