[英]Generic interface inheritance castings
當前,我面臨一個通用接口繼承問題:
interface IParent<T> {
R Accept<R>(IParentVisitor<T, R> visitor);
}
interface IChild<T, TKey> : IParent<T> {
R Accept<R>(IChildVisitor<T, TKey, R> visitor);
}
我還創建了以下Visitor
接口:
interface IParentVisitor<T, R> {
R Visit(IParent<T> parent);
}
interface IChildVisitor<T, TKey, R> : IParentVisitor<T, R> {
R Visit(IChild<T, TKey> viz);
}
實現方式:
class ParentVisitor<T> : IParentVisitor<T, MyResultClass> {
MyResultClass Visit(IParent<T> parent) {
return //...;
}
}
class ChildVisitor<T, TKey> : IChildVisitor<T, TKey, MyAnotherResultClass> {
MyAnotherResultClass Visit(IChild<T, TKey> child) {
return //...;
}
}
到目前為止,一切似乎都是正確的。 但是,請猜測這種情況:
static void Main() {
IList<IParent<MyT>> interfaces = new List<IParent<MyT>>();
interfaces.add(new Parent<MyT>());
interfaces.add(new Child<MyT, string>());
interfaces.add(new Child<MyT, int>());
interfaces.add(new Child<MyT, TimeSpan>());
//...
//(!!*!!)
foreach (IChild<MyT, string> stringChild in interfaces.OfType<IChild<MyT, string>()) {
ChildVisitor stringChildVisitor = new ChildVisitor<MyT, string>();
var result = stringChild.Accept(stringChildVisitor);
//...
}
//(!!*!!)
foreach (IChild<MyT, int> intChild in interfaces.OfType<IChild<MyT, int>()) {
ChildVisitor intChildVisitor = new ChildVisitor<MyT, int>();
var result = stringChild.Accept(intChildVisitor);
//...
}
//and so on up to infitiny types in C#...
}
我認為這是獲取我想要的東西的不可行方法。
我想要獲得的是對IChild<T, *>
上的任何一個使用ChildVisitor
,其中*
是任何類型。 我不知道我的解釋是否很好。
像這樣:
//(!!*!!)
foreach (IChild<MyT, *> asterisckChild in interfaces.OfType<IChild<MyT, *>()) {
ChildVisitor asterisckChildVisitor = new ChildVisitor<MyT, *>();
var result = asterisckChild.Accept(asterisckChildVisitor);
//...
}
有任何想法嗎?
IList list = new ArrayList();
list.Add(new Dictionary<string, string>
{
["key"] = "value"
});
list.Add(new Dictionary<string, int>()
{
["key"] = 123
});
list.Add("just for the test");
foreach(var it in list)
{
foreach(var face in it.GetType().GetInterfaces())
{
//1. Filter out non-generic interfaces
// (following GetGenericTypeDefinition() would throw exception otherwise)
if (!face.IsGenericType)
continue;
//2. Filter out anything that is not IDictionary<,>
if (typeof(IDictionary<,>) != face.GetGenericTypeDefinition())
continue;
//3. Filter out anything that is not IDictionary<string,>
var generic = face.GetGenericArguments();
if (typeof(string) != generic[0]) //note: consider IsAssignableFrom instead
continue;
//4. Invoke the method
var valueType = generic[1];
var method = face.GetMethod("TryGetValue"); //note: needs to be more specific if overloaded
//don't know how you want to choose R for the Accept<R>
//method = method.MakeGenericMethod(new[] { typeof(R) });
var arguments = new object[] { "key", null };
method.Invoke(it, arguments);
var value = arguments[1];
//5. Do something with the result
Console.WriteLine(value.ToString());
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.