【问题标题】:Make a castable type from GetType?从 GetType 制作可转换类型?
【发布时间】:2020-12-09 05:47:22
【问题描述】:

在下面的代码sn-p中进行了解释,我无法弄清楚它的语法:

object tcsObject = new TaskCompletionSource<Apple>();
Apple apple = new Apple();

// How do I do this?
TaskCompletionSource<apple.GetType>() tsc = tscObject as TaskCompletionSource<apple.GetType>()

编辑 应该注意我试图弄清楚的特定问题是如何在最初不知道类型是 Apple 的情况下进行这种泛型转换。类型最终可能是任何东西,所以我希望从通过 GetType 返回的内容中执行此操作。

【问题讨论】:

  • 您可以使用反射,但问题是所有将使用它的进一步代码也需要使用反射。将其屏蔽为TaskCompletionSource&lt;object&gt; 不是更好吗?
  • 您不能将动态类型传递给泛型。泛型是编译时的概念,GetType 在运行时运行
  • 你不能。编译器需要在编译时知道每个变量的类型。使用已知的固定类型或使用您自己的范围内泛型类型参数。
  • 在那个例子中,类型总是Apple,那你为什么不直接使用TaskCompletionSource&lt;Apple&gt;呢?
  • 您可以创建一个方法,其中包含需要使用TaskCompletionSource&lt;T&gt; 的所有代码,然后使用反射来调用该方法,那么您至少可以最大限度地减少所需的反射量。

标签: c# generics reflection


【解决方案1】:

如果您不介意牺牲编译时类型安全,您可以像这样使用Convert.ChangeType()dynamic 关键字:

static dynamic ConvertTo(this object source, Type targetType)
{
    return (dynamic)Convert.ChangeType(source, targetType)
}

public void YourActualCode()
{
    object tcsObject = new TaskCompletionSource<Apple>();
    Apple apple = new Apple();

    TaskCompletionSource<Apple> tsc = ConvertTo(tscObject, typeof(TaskCompletionSource<Apple>))
}

这种方法的好处是您可以将参数类型的确定推迟到运行时:

var wrapperType = typeof(TaskCompletionSource<>);
var paramType = typeof(Apple);

var concreteType = wrapperType.MakeGenericType(paramType);

TaskCompletionSource<Apple> tsc = ConvertTo(tscObject, concreteType);

【讨论】:

  • 谢谢你。我真正想弄清楚的是如何从 GetType 生成泛型类型。特别是apple.GetType。因为我正在努力解决的问题是我不知道苹果最终可能是哪种类型。
  • @rygo6 那么你肯定想要typeof(TaskCompletionSource&lt;&gt;).MakeGenericType(apple.GetType()) :)
猜你喜欢
  • 1970-01-01
  • 2011-11-09
  • 2018-04-07
  • 1970-01-01
  • 2021-01-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-02
相关资源
最近更新 更多