Interface :- Alternative Approach
I am beginner.Practicing in C# 3.0. The requirement is "i have to design model in such a way that ,it should iterate through all classes which implement particular interface
(in this case IExpressWords
) and execute the implemented method (void ExpressWords()
)"
I collected all classes in a List and iterated.
namespace InterfaceExample
{
public interface IExpressWords
{
void ExpressWords();
}
class GroupOne:IExpressWords
{
string[] str = { "Good", "Better", "Best" };
public void ExpressWords()
{
foreach (string s in str)
{
Console.WriteLine(s);
}
}
}
class GroupTwo:IExpressWords
{
string[] str = { "one", "two", "three" };
public void ExpressWords()
{
foreach (string s in str)
{
Conso开发者_开发问答le.WriteLine(s);
}
}
}
class Test
{
static void Main()
{
List<IExpressWords> word = new List<IExpressWords>();
word.Add(new GroupOne());
word.Add(new GroupTwo());
foreach (IExpressWords Exp in word)
{
Exp.ExpressWords();
}
Console.ReadKey(true);
}
}
}
Questions :
- What is the name of this pattern ? ( chain-of-responsibility? )
- How can i achieve it using delegates ( I am not strong in delegates).
- How can i find out all classes that implement the interface and execute the method using reflection ?(Curious to know ,how to tackle it using reflection).
(If i am not so clear in description,kindly let me know).
Thanks all for the pouring perennial responses.
1) It's the strategy pattern
2) Since the IExpressWords interface only contains a single method, it is effectively a wrapper around a method, which is what delegates are for. The equivalent delegate type is Action. So your code would then become:
var groupOne = () =>
{
foreach(string s in new[] { "Good", "Better", "Best" })
{
Console.WriteLine(s);
}
}
var groupTwo = () =>
{
foreach(string s in new[] { "one", "two", "three" })
{
Console.WriteLine(s);
}
}
List<Action> acts = new List<action> { groupOne, groupTwo };
foreach(var a in acts)
{
a();
}
3) To find all the types that implement an interface in the current assembly you can do this:
a = Assembly.GetExecutingAssembly();
var implementingTypes = a.GetTypes().Where(t => typeof(IExpressWords).IsAssignableTo(t));
you can use Action class to achieve this using delegates if you like
class Test
{
static void Main()
{
List<Action> word = new List<Action>();
word.Add(new GroupOne().ExpressWords());
word.Add(new GroupTwo().ExpressWords());
foreach (Action del in word)
{
del();
}
Console.ReadKey(true);
}
}
if you want to use Delegates then you have to declare a Delegate type
delegate void SomeMethod();
class Test
{
static void Main()
{
List<SomeMethod> word = new List<SomeMethod>();
word.Add(new GroupOne().ExpressWords());
word.Add(new GroupTwo().ExpressWords());
foreach (SomeMethod del in word)
{
del();
}
Console.ReadKey(true);
}
}
Regarding the reflection case here is a small example :
static void WreakHavoc<T>(Action<T> havok)
{
var assemblies = AppDomain.CurrentDomain.GetAssemblies();
var implementing = from assembly in assemblies
from type in assembly.GetTypes()
let interfaceType = typeof(T)
where interfaceType.IsAssignableFrom(type)
select type;
foreach(var type in implementing)
{
var ctor = type.GetConstructor(Type.EmptyTypes);
if (ctor == null) continue;
var instance = (T)ctor.Invoke(new object[0]);
havok(instance);
}
}
static void Main()
{
WreakHavoc<System.Collections.IEnumerable>((e) =>
{
foreach (var o in e)
{
Console.WriteLine(o);
}
});
}
精彩评论