Reputation: 1367
I am having some trouble designing a solution that uses command pattern but with generics. Basically, I have defined a generic interface that has just one method that returns a list of generic object.
public interface IExecute<T>
{
List<T> Execute();
}
public class SimpleExecute : IExecute<int>
{
public List<int> Execute()
{ return a list of ints... }
}
public class Main
{
private List<IExecute<T>> ExecuteTasks; // This is not valid in C#
}
Since generic list of generics isn't valid, I implemented a non-generic interface IExceute and made the generic interface extend the non-generic one and was able to create a list
public interface IExecute {}
public interface IExecute<T> : Execute
{
List<T> Execute();
}
private List<IExecute> ExecuteTasks;
However, now I am not sure how can I loop through the ExecuteTasks and call the execute method.
I have tried my best to explain the issue. Please, let me know if you need further explanation of my issue.
Thanks
Upvotes: 0
Views: 213
Reputation: 4603
When you are using generics, consider that IExecute<Class1>
is a completely different interface than IExecute<Class2>
. In this case, if you were to invoke a common method in both, you'd need another interface; e.g. IExecute
.
public interface IExecute<T>
{
List<T> Execute();
}
public interface IExecute
{
IList Execute();
}
public class SimpleExecute : IExecute<int>, IExecute
{
IList IExecute.Execute()
{
return Execute();
}
public List<int> Execute()
{
return new List<int>();
}
}
Then, to loop you can simply use foreach and/or LINQ.
List<IExecute> entries = new List<IExecute> {new SimpleExecute()};
foreach (var result in entries.Select(x => x.Execute()))
{
}
What you are trying to achieve seems correct because you consider IExecute as a single interface, but in fact it is a "template" for an interface which will be created at compile time.
Upvotes: 0
Reputation: 2320
List<IExecute<T>> ExecuteTasks
is not valid because T is not defined anywhere in the containing class.
Something like this should work instead though:
List<IExecute<Object>> ExecuteTasks;
ExecuteTasks.Add(new SimpleExecute());
Or
public class Main<T>
{
List<IExecute<T>> ExecuteTasks
}
Upvotes: 1
Reputation: 43046
The best you can do is this:
public interface IExecute { IList Execute(); }
Then, for example:
public class SimpleExecute : IExecute<int>
{
public List<int> Execute()
{ return a list of ints... }
IList IExecute.Execute() { return this.Execute(); }
}
(Note the explicit interface member implementation for the non-generic IExecute.Execute()
)
Then:
List<IExecute> iExecuteList = //whatever;
foreach (var ix in iExecuteList)
{
IList list = ix.Execute();
}
You can't get the specific generic list type at compile time (for example, IList<string>
, IList<int>
) for the same reason you can't store an int
and a string
in the same generic list (unless the type argument is object
).
Upvotes: 2
Reputation: 111
public class Main
{
private List<IExecute<T> ExecuteTasks; // This is not valid in C#
}
There are 2 errors here:
T is an unknown class. You should have specified the correct type
List< doesn't have a close angle bracket '>'. Each opening bracket must have a closing one. It should look like List<IExecute<T>>
Upvotes: 1
Reputation: 4739
Try looping through every item by using a foreach
loop:
foreach(var item in ExecuteTasks)
{
item.Execute();
//...
}
Upvotes: 0