2012-07-25 29 views
2

我正在寻找一种方法来定义“治法”以下,例如,它返回一个类定义(System.Type的),其中的一个实例说类型实现“InterfaceB”如何创建返回实现接口的类的Type的方法的通用接口?

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

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

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

在此先感谢您的任何指导。

编辑:

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

我还没有真正:我在的是更具体的,什么是返回是System.Type的,其中这个后面的代码可以执行的希望更新这关注这个部分,只是对我的主要问题的理论构造更加好奇。

+0

将返回类型更改为'TInterface' – asawyer 2012-07-25 22:21:17

+0

您是使用“Type”来表示“System.Type”,还是意味着您已经定义了某种类型?在前一种情况下,由于显而易见的原因,你试图做的事情是不可能的,而且你几乎肯定不应该从'System.Type'派生出来。 – 2012-07-25 22:30:53

+0

是的,我的意思是System.Type。我试图看看是否可以获得实现TInterface的类定义,其中稍后我将对其进行“新增”处理。我试图避免在这个特殊的方法中使用新的方法。 – Eric 2012-07-26 14:10:57

回答

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>(); 

The type 'DoesNotImplementB' cannot be used as type parameter 'TClass' in the generic type or method 'MethodA<TClass,TInterface>()'. There is no implicit reference conversion from 'DoesNotImplementB' to 'InterfaceB'.

所以,这样你肯定的MethodA结果是实现TInterface类的Type。鉴于Type对象,你可以instantate它以后是这样的:

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); 
} 

但是,如果typeType某种程度上不执行TInterface,您将在运行时得到一个InvalidCastException。没有办法将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变量,反之亦然。

这是你想知道的吗?

+0

关闭,但我试图避免实际实例化对象在这一点上。我想返回类定义本身,我可以使用它来稍后实例化对象。我的问题是我找不到一种方法来保证返回的(System.Type),实例化时,实际上实现了TInterface。至少,直到我尝试实例化它并将其投影到TInterface。但这是一个运行时解决方案,而不是编译时解决方案。 – Eric 2012-07-26 14:17:40

+0

我更新了我的帖子。这更接近你想知道的吗? – Virtlink 2012-07-26 14:45:14

+0

我没有忘记这件事,我只是没有时间去应用你的想法。他们听起来不错,也许我会有机会在这个周末尝试一下,并且尽可能地更新这个评论块。 – Eric 2012-07-27 20:35:22

3

对你的问题有两种解释;一个是微不足道的,一个是不可能的,所以我会前进并覆盖两者。

  1. 你想返回同时实现System.TypeTInterface一个类型的实例。

    这很简单:只需使用where TType : Typewhere TType : TInterface即可。

  2. 想要返回表示从TInterface继承的类型的System.Type的实例。

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

    类型系统只能解析来自类型层次结构本身的信息,但不会像限制的运行时属性值那样强制执行“契约”。关于默认构造函数等,有一些窍门,但据我所知,即使对现有方法进行测试也是不可能的(例如,与C++模板不同,不用说Qi等人)。

更新

,请以Michael Graczyk评论。

另外:我刚刚发现有代码合同检查器(静态和运行时)的.NET:Microsoft DevLabs Code-Contracts for .NET。我从来没有用过它们,甚至没有对它们进行过新的介绍,但看起来很有趣!

但是,即使没有看,我很确定重载决议等将无法使用这些信息。

+1

3.他正在使用“Type”这个词来表示“System.Type”以外的内容。 – 2012-07-25 22:31:51

+0

对此,你是如此的正确。哎哟。对于其他读者:属于第2类)检查属性值不起作用。 – gimpf 2012-07-25 22:33:21

+0

#1,我会简化它为 其中TType:类型,TInterface – Eric 2012-07-26 14:12:23