C#通行证泛型在运行时
我有类似下面的方法:C#通行证泛型在运行时
public IEnumerable<T> GetControls<T>()
: where T : ControlBase
{
// removed.
}
然后,我创建了一个类:
public class HandleBase<TOwner> : ControlBase
: TOwner
{
// Removed
}
我希望能够调用
GetControls<HandleBase<this.GetType()>>;
它将使用该类的类型传递给HandleBase。这基本上会得到所有拥有这种类型的HandleBase。
我该如何做到这一点?
编辑:
我使用.NET 2.0解决方案,所以大于2.0将无法正常工作。
这个想法是让ControlBase拥有其他ControlBase for“children”的集合。然后他们可以根据他们的类型与GetControls<T>()
查询。例如,这可以让我得到一个Shape的所有HandleBase。然后,我可以采取所有这些,并设置Visible = false或与他们一起做其他事情。因此,我可以操纵特定类型的儿童进行收藏。
HandleBase<TOwner>
需要陶纳,因为它具有与“拥有类型”的引用。所以你只能添加任何将HandleBase扩展到Shape的东西。合理?
感谢您的帮助!
这是具体到我实现这一点,但我可以通过创建一个非通用HandleBase
,然后再一个通用HandleBase<TOwner>
,因为唯一的地方来解决这个TOWNER正在使用的是业主。
然后,当我可以调用GetControls<HandleBase>
并获得所有的HandleBase而不管所有者。
谢谢你的回答!
你不能。泛型是一个编译时功能。您需要将该类型作为非泛型参数包含在该方法中,并将其传递给该方法。
你可以使用反射来做到这一点。但是对于问题中所描述的内容来说,这看起来真是太过于夸张了。我同意将类型引用传递给函数。 – 2010-04-09 14:31:44
System.Reflection.Assembly a = System.Reflection.Assembly.GetExecutingAssembly(); 类型t = a.GetType(“SeaSharpWinApp8.Program”); MethodInfo mi = t.GetMethod(“f”,BindingFlags.Static | BindingFlags.NonPublic); MethodInfo miGeneric = mi.MakeGenericMethod(new Type [] {typeof(string)}); miGeneric.Invoke(null,new object [] {“works”}); – 2010-04-09 14:47:44
这是MakeGenericMethod调用,可以让你做到这一点。您必须先获取MethodInfo,然后再获取您想要使用的特定类型。如果它是一个泛型类型,那么你在类型级别进行MakeGeneric *调用。 – 2010-04-09 14:48:42
您可以通过在编译时指定类型或使用反射来执行此操作。
你可以用反射像这样做:
typeof(SomeClass).GetMethod("GetControls")
.MakeGenericMethod(typeof(HandleBase<>).MakeGenericType(GetType()))
.Invoke(someObject, null);
注意,它会返回一个object
;你将无法将其转换为IEnumerable<T>
(除非你知道编译时T
是什么,在这种情况下没有意义)。你可以将它投射到IEnumerable
。
但是,这是一个坏主意。
您可能有更好的解决方案;请提供更多细节。
请注意,类型参数不是变量。因此,您不能使用变量来代替类型参数。
你可以,但是,做到这一点通过反射,或通过使用特殊结构,这是非常有限的,但可以解决您的情况:
public class MyClass<TSelf> where TSelf: MyClass<TSelf> {
public IEnumerable<T> GetControls<T>() where T: ControlBase {
// removed.
}
public void MyCall() {
GetControls<HandleBase<TSelf>>();
}
}
public class MyConcreteClass: MyClass<MyConcreteClass> {
}
有可能是没有办法的事,你问什么。扩展你的例子:
X x = GetControls<HandleBase<this.GetType()>>;
什么样的X应该在这里?但是从其他背景信息看来,您需要获取给定类型的所有控件的列表。你可以在这样的方式,例如做到这一点:
public IEnumerable<ControlBase> GetControls(Type type) {
//your logic here
}
根据您的其他用途,你可能也想返回非通用IEnumerable的目标。
的GetControls以来()返回一个枚举,你可能会找到一个方法来生成的枚举与.OfType <牛逼>,像
List<T2> list = controlList.GetControls<T>().OfType<T2>().ToList();
过滤您将需要一个通用的限制somehwere沿
线where T2 : T
特定于> = 3.0,我忘记提及我正在使用2.0。 – TheCloudlessSky 2010-04-09 16:08:54
@TheCloudlessSky,为什么调用'this.GetType()'?如果你正在调用'GetControls>();'从一个基于实例的类[如'this'指示],为什么不简单地使用实现类的声明类型名?如果这是一个基类,则有将子类的类型暴露给基类的方法。 –
2010-04-09 14:46:33
请参阅上面的修改。 – TheCloudlessSky 2010-04-09 16:07:41