2

我正在寻找一种在下面定义“MethodA”的方法,以便它返回一个类定义(System.Type),其中所述类型的实例实现“InterfaceB”

interface IMyInterface
{
  TType MethodA<TType, TInterface>() 
    : where TType : System.Type
    : where [instanceOf(TType)] : TInterface
}

(注意:instanceOf 不是真实的,当然……)

我怀疑在编译时不可能得到这种验证。我希望有人能证明我错了。

提前感谢您的任何指导。

编辑:我已经更新了这个,希望更具体地说,返回的是一个 System.Type,后面的代码可以执行它:

var classType = myInterface.MethodA<(something, ISomeInterface)>();
ISomeInterface = new classType();  //--Assuming default constructor

我还没有真正专注于这部分,只是对我的主要问题的理论结构更加好奇。

4

2 回答 2

3

您的问题有两种解释;一个是微不足道的,一个是不可能的,所以我会继续介绍两者。

  1. 您想返回一个同时实现System.Type和的类型的实例TInterface

    这很简单:只需使用where TType : Typeand where TType : TInterface

  2. 您想返回一个System.Type表示继承自 的类型的实例TInterface

    这是不可能在 .NET(和 C#)类型系统中指定的。

    类型系统只能解析来自类型层次结构本身的信息,但不能强制执行“合同”,例如受限的运行时属性值。关于默认构造函数等有一些技巧,但据我所知,甚至无法测试现有方法(例如,与 C++ 模板不同,更不用说 Qi 等人了)。

更新

请查看Michael Graczyk的评论。

另外:我刚刚发现.NET 有代码合同检查器(静态和运行时):Microsoft DevLabs Code-Contracts for .NET。我从未使用过它们,甚至对它们都不陌生,但这看起来很有趣!

但是,即使不看,我也很确定重载解析等将无法使用此类信息。

于 2012-07-25T22:30:40.543 回答
0

在这个情况下:

// We have an interface...
interface InterfaceB {}

// And this class implements the interface.
class ImplementsB : InterfaceB {}

// But this class does not.
class DoesNotImplementB {}

你可以定义MethodA为:

static Type MethodA<TClass, TInterface>()
    where TClass : TInterface
{
    return typeof(TClass);
}

然后以下将起作用:

Type t = MethodA<ImplementsB, InterfaceB>();

但这会产生编译时错误:

Type t = MethodA<DoesNotImplementB, InterfaceB>();

类型“DoesNotImplementB”不能用作泛型类型或方法“MethodA<TClass,TInterface>()”中的类型参数“TClass”。没有从“DoesNotImplementB”到“InterfaceB”的隐式引用转换。

因此,通过这种方式,您可以确定 的结果MethodA是一个Type实现TInterface. 给定该Type对象,您可以稍后像这样实例化它:

public object Instantiate(Type type)
{
    // Call the default constructor.
    // You can change this to call any constructor you want.
    var constructor = type.GetConstructor(Type.EmptyTypes);
    var instance = constructor.Invoke(new object[0]);
    return instance;
}

如果您知道您Type的接口与某些接口兼容TInterface,那么您可以使用这样的附加方法来避免强制转换:

public TInterface Instantiate<TInterface>(Type type)
{
    return (TInterface)Instantiate(type);
}

但是,如果type是 aType以某种方式无法实现TInterface,您将InvalidCastException在运行时得到 a 。没有办法限制Type为在编译时实现特定接口的类型。但是,在运行时您可以检查它以避免InvalidCastException异常:

public TInterface Instantiate<TInterface>(Type type)
{
    if (!typeof(TInterface).IsAssignableFrom(type))
        throw new Exception("Wrong type!");
    return (TInterface)Instantiate(type);
}

请注意,这typeof(TType)是一个生成Type对象的表达式,因此在您看到的任何地方都typeof()可以用任何Type变量替换它,反之亦然。

这是你想知道的吗?

于 2012-07-26T00:08:32.853 回答