繁体   English   中英

C#在运行时传递泛型

[英]C# Pass Generics At Runtime

我有一个像下面这样的方法:

public IEnumerable<T> GetControls<T>()
 : where T : ControlBase
{
 // removed.
}

然后我创建了一个类:

public class HandleBase<TOwner> : ControlBase
 : TOwner
{
 // Removed
}

我想能打电话

GetControls<HandleBase<this.GetType()>>; 

它将使用THIS类的类型传递给HandleBase。 这基本上会使所有拥有此类型所有者的HandleBase。

我怎样才能做到这一点?

编辑:

我正在使用.NET 2.0,因此大于2.0的解决方案将无效。

这个想法是让ControlBase拥有一个其他ControlBase的集合,用于“孩子们”。 然后可以使用GetControls<T>()根据类型查询它们。 例如,这将允许我为Shape获取所有HandleBase。 然后我可以采取所有这些并设置Visible = false或用它们做其他事情。 因此,我可以为一个集合操纵特定类型的孩子。

HandleBase<TOwner>需要TOwner,因为它引用了“拥有类型”。 因此,您只能添加任何将HandleBase扩展到Shape的内容。 说得通?

感谢您的帮助!

您可以通过在编译时指定类型或使用反射来执行此操作。

你可以用这样的反射做到这一点:

typeof(SomeClass).GetMethod("GetControls")
    .MakeGenericMethod(typeof(HandleBase<>).MakeGenericType(GetType()))
    .Invoke(someObject, null);

注意它会返回一个object ; 你将无法将其IEnumerable<T>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 <T>过滤生成的枚举,类似于

List<T2> list = controlList.GetControls<T>().OfType<T2>().ToList();

你需要一个通用的约束

where T2 : T

这特定于我对此的实现,但我能够通过先创建一个非通用的HandleBase然后再创建一个通用的HandleBase<TOwner>来解决这个问题,因为唯一使用TOwner的地方是属性所有者。

然后当我可以调用GetControls<HandleBase>并获得所有HandleBase而不管所有者。

谢谢大家的回答!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM