【发布时间】:2017-05-05 11:53:48
【问题描述】:
这里有一个虚拟代码来解释我的问题:
public class A<TX, TA> where TA : A<TX, TA>
{
}
public void Do()
{
var doy = typeof(A<,>).MakeGenericType(typeof(string), null/*??????*/));
}
如果我无法识别我的类型以将其用作参数,我如何从我的泛型类型中创建一个类型?
感谢您的帮助。
编辑,静态执行的示例:
public abstract class A<TX, TA> where TA : A<TX, TA>
{
public TA ChainMethod()
{
return (TA)this;
}
}
public class AConcrete : A<string, AConcrete>
{
public AConcrete OtherMethod()
{
return this;
}
}
public class App
{
public static void Start()
{
new AConcrete().ChainMethod().ChainMethod().OtherMethod();
}
}
【问题讨论】:
-
如果这是 CRTP - 它会变得非常难看;你会如何用 C# 来表达它?
A<string, A<string, A<string, A<string, ........? -
你不能。但是添加“动态”是一条红鲱鱼 - 它不像有任何方法可以静态地做到这一点。
A<string, ???>-- 我如何扩展“???”?一定有一个基地在某个地方。该类本身是合法的,但您至少需要一个其他类来引导它。 Eric Lippert's comments 关于这令人困惑并且可能无法实现您想要的东西仍然有效。 -
你能解释一个更高级的需求吗?
-
您希望动态执行该代码的哪一部分?动态生成
AConcrete?无论如何,您都需要将其作为单独的类型。你不能调用.MakeGenericType来传递你正在创建的相同类型。您可以生成一个从泛型类型继承的类型,并将其自身作为类型参数,正如 C# 代码所做的那样(使用ModuleBuilder.DefineType)——但这是在运行时创建类型,而不仅仅是实例化泛型类型。 -
这是可能的,但在后一种情况下你仍然需要
DefineType,这听起来比必要的复杂得多。考虑一些具有非泛型类的泛型方法的解决方案,这些方法往往要简单得多。或者使用Dictionary或Types 的某种方法来映射事物。不要太沉迷于泛型——无论如何,一旦你在运行时做事,类型安全就不是很好了。