I have a method that receives and action (previously was action < bool >, but now I need more types allowed):
public void Runaction<T>(Action<T> _ActionCallback)
{
StackAction.Add(_ActionCallback);
...etc
}
Previously, my list stackAction was:
readonly List<Action<bool>> StackAction= new List<Action<bool>>()
But now I need this list to allowed type bool but byte[] too
When I declare
readonly List<Action<T>> StackAction= new List<Action<T>>()
it returns T does not exists.
What is the workaround for this need?
There is no diamond operator <>
in C# and .NET does not support true generic polymorphism on open types yet.
Generics open and closed constructed types
Thus we can't write:
readonly List<Action<>> StackAction = new List<Action<>>();
To allow a list of action of any one type parameter.
Moreover, this case of true generic polymorphism on delegates is more complicated to manage compared to classes or interfaces or value types.
But you can manage each type you want like that:
public class MyClass
{
private readonly List<object> StackAction = new List<object>();
public void Runaction<T>(Action<T> _ActionCallback)
{
switch ( _ActionCallback )
{
case Action<bool> action:
StackAction.Add(action);
action(GetBoolParameter());
break;
case Action<byte[]> action:
StackAction.Add(action);
action(GetByteArrayParameter());
break;
default:
string message = $"Type not supported for Runaction<T>." + Environment.NewLine
+ $"Only bool or byte[] is allowed." + Environment.NewLine
+ $"Type provided: {typeof(T).Name}";
throw new ArgumentException(message);
}
}
private bool GetBoolParameter()
{
return false;
}
private byte[] GetByteArrayParameter()
{
return new byte[] { 1, 2, 3, 4, 5 };
}
}
Test
Action<bool> actionBool = value =>
{
Console.WriteLine(value.GetType());
};
Action<byte[]> actionByteArray = value =>
{
Console.WriteLine(value.GetType());
};
Action<int> actionInt = value =>
{
Console.WriteLine(value.GetType());
};
var instance = new MyClass();
instance.Runaction(actionBool);
instance.Runaction(actionByteArray);
try
{
instance.Runaction(actionInt);
}
catch ( Exception ex )
{
Console.WriteLine(ex.Message);
}
Output
System.Boolean
System.Byte[]
Type not supported for Runaction<T>.
Only bool or byte[] is allowed.
Type provided: Int32