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 的集合。然后可以使用 GetControls
根据其类型来查询它们。例如,这将使我能够获取形状的所有 HandleBase。然后我可以获取所有这些并设置 Visible=false 或对它们执行其他操作。因此我可以操作集合的特定类型的子项。
HandleBase
需要 TOwner,因为它具有对“所属类型”的引用。因此,您只能添加将 HandleBase 扩展为 Shape 的任何内容。有道理吗?
感谢您的帮助!
I have a method like the following:
public IEnumerable<T> GetControls<T>()
: where T : ControlBase
{
// removed.
}
I then created a class:
public class HandleBase<TOwner> : ControlBase
: TOwner
{
// Removed
}
I'd like to be able to call
GetControls<HandleBase<this.GetType()>>;
where it would use the type of THIS class to pass to the HandleBase. This would in essentially get all HandleBase that have an owner of THIS type.
How can I achieve this?
EDIT:
I'm using .NET 2.0 so solutions greater than 2.0 will not work.
The idea is to have ControlBase have a collection of other ControlBase for "children". Then they can be queried based on their type with GetControls<T>()
. This would allow me to, for example, get all HandleBase for a Shape. Then I can take all of these and set Visible=false or do something else with them. Thus I can manipulate children of a specific type for a collection.
HandleBase<TOwner>
requires the TOwner since it has a reference to the "owning type". So you can only add anything that extends HandleBase to a Shape. Make sense?
Thanks for all the help!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
您可以通过在编译时指定类型或使用反射来完成此操作。
您可以使用反射来完成此操作,如下所示:
请注意,它将返回一个
对象
;您将无法将其转换为IEnumerable
(除非您在编译时知道T
是什么,在这种情况下没有意义)。您可以将其转换为IEnumerable
。然而,这是一个坏主意。
可能有更好的解决方案适合您;请提供更多详细信息。
You can do this either by specifying a type at compile-time or by using reflection.
You can do it with reflection like this:
Note that it would return an
object
; you would not be able to cast it toIEnumerable<T>
(Unless you know whatT
is at compile-time, in which case there's no point). You would be able to cast it toIEnumerable
.However, this is a bad idea.
There is probably a better solution for you; please provide more detail.
你不能。泛型是一个编译时功能。您需要将该类型作为非泛型参数包含到该方法中,并将其传递到那里。
You can't. Generics is a compile-time feature. You would need to include the type as a non-generic parameter to the method, and pass it in there.
请注意,类型参数不是变量。因此,不能使用变量来代替类型参数。
但是,您可以通过反射或使用特殊的构造来完成此操作,该构造非常有限,但可以解决您的情况:
Note that type parameters are not variables. Therefore, you cannot use a variable in place of a type parameter.
You could, however, do this through reflection, or by using a special construct which is pretty limited but may solve your case:
可能没有办法做到你所要求的。扩展你的例子:
这里的类型 X 应该是什么?然而,从其他背景信息来看,您似乎需要获取给定类型的所有控件的列表。例如,您可以通过以下方式执行此操作:
根据您的其他用法和目标,您可能还想返回非泛型 IEnumerable。
Probably there is no way to do what you ask for. Extending your example:
What should the type X be here? However from other background information it seems that you need to get list of all controls of given type. You could do this for example in such way:
Depending on your other usages and goals you might also want to return non-generic IEnumerable.
由于 GetControls() 返回一个枚举,您可能会找到一种方法来使用 .OfType过滤生成的枚举,例如
您需要一个通用约束,类似于
Since GetControls() returns an enumeration, you might find a way to filter the resulting enumeration with .OfType<T>, something like
You would need a generic constraint somehwere along the lines of
这是特定于我的实现的,但我能够通过首先创建一个非通用
HandleBase
然后创建一个通用HandleBase
来解决这个问题,因为唯一的地方 TOwner正在使用的是业主。然后,当我可以调用
GetControls
并获取所有 HandleBase 时,无论所有者是谁。谢谢大家的解答!
This is specific to my implementation of this but I was able to solve this by creating a non-generic
HandleBase
first and then a genericHandleBase<TOwner>
since the only place TOwner was being used was the property Owner.Then when I can call
GetControls<HandleBase>
and get all HandleBase regardless of the Owner.Thanks all for answers!