1

所以对于两个不同的命名空间,我有一个类 Record。我想根据传入的类型返回适当的类型。为了尝试执行此操作,我尝试过此操作,但“T2”不正确。我怎样才能做到这一点?

public T2 GetGeneratedType<T1>(string name) where T1 : class where T2 : class
{
  var type = typeof(T1);
  var generatedName = type.AssemblyQualifiedName.Replace(type.Name, name);
  return (T2)Activator.CreateInstance(Type.GetType(generatedName));
}

我还没有测试过这个(显然不会编译),但是我如何使它工作,以便如果我传入 Namespace1.SomeClass,我会得到 Namespace1.Record,如果我传入 Namespace2.SomeOtherClass,我会得到Namespace2.Record(只要 name == "Record")。

我最初尝试 T 一切,它没有给出任何错误消息,但我想确保输入和输出类型被允许是不同的类型。

编辑:

我可能没有完全解释清楚。

我正在为分叉记录创建数据注释(从技术上讲,由于对他们执行 3 个不同的过程,因此需要能够在任何给定时间为 3 个人分配此记录。一旦完成 3 个过程,它们就会被核对) . 所以 namespace1 是一个项目(不是 Visual Studio 意义上的),而 namespace2 是另一个项目。在 namespace1 中,您有一个 ImportedRecord1 和在 namespace2 ImportedRecord2 (两个具有单独属性的独立项目,尽管或多或少具有相同的目的)。Namespace1 和 Namespace2 都具有与特定命名空间的 ImportedRecord 相关的 Record 类型,然后将分叉到不同类型的 3 个“子记录”(基本上是该项目的导入记录,但具有与 3 个进程之一相关的字段)。

4

3 回答 3

5

您只需要将第二种类型声明为泛型方法签名的一部分。

public T2 GetGeneratedType<T1, T2>(string name) where T1 : class where T2 : class
{
  var type = typeof(T1);
  var generatedName = type.AssemblyQualifiedName.Replace(type.Name, name);
  return (T2)Activator.CreateInstance(Type.GetType(generatedName));
}

编辑:

这与您的问题并没有直接关系,但无论如何我都会把它扔进去。我不认为这种设计真的会给你任何价值代码减少或其他......

  • 您不会像使用 Factory 那样将类解耦,因为现在您返回了一个object您将被迫在另一边强制转换的类型。

  • 在运行时利用反射创建这些对象时,您也会损失轻微的性能。

  • 对于这种特定场景来说,这只是一个一次性的功能,而像这样的做法如果长期存在,可能会导致代码混乱。

于 2013-05-02T17:33:43.407 回答
2

您需要做的就是将返回类型设置为动态而不是 T2。类型将在运行时确定。

于 2013-05-02T17:58:51.183 回答
1

泛型类型参数只能“进入”函数调用。一个函数可以有一个通用的返回值,但是返回值的类型必须由调用者提供[当然,一个返回某种类类型的函数可以返回T对一个实例的引用任何派生自 的类型T,但调用者仍会看到返回值的类型T为,但这种方法有一些局限性。例如,人们可能知道返回的对象将属于满足独立约束的类型,IFoo并且IBar,但可能返回的事物的类型可能不共享任何同样实现IFoo和的公共超类型IBar。没有很好的保持身份的方法可以将这样的返回值传递给需要同时满足约束IFooIBar约束的方法,因为没有可以将所有可能值转换为的单一类型。

解决此限制的一种方法是让函数公开对象,而不是将其返回给调用者,而是将其传递给调用者提供的对象中的泛型方法。例如,如果定义了一个接口:

interface IFooBarConsumer { PerformAction <T>(T thing) where T:IFoo,IBar; }
interface IFooBarFeeder { FeedItem(IFooBarConsumer theConsumer); }

如果实现的类IFooBarFeeder有一个它知道满足IFoo和的对象IBar,它可以将该对象传递给传入的IFooBarConsumer,而该消费者又可以将其传递给同时具有IFooIBar约束的方法。必须给代码一个消费者,而不是简单地从它那里接收一个对象,这可能很尴尬,但它允许人们以类型安全的方式做一些原本不可能的事情。

于 2013-05-02T21:12:48.617 回答