Reputation: 11
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
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)
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
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
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
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