2011-02-13 154 views
1

首先,我知道标题不是很好,但事实是我甚至不知道如何解释我的问题;我将在下面展示一个我想要做的事例:类型推断问题:非泛型方法的泛型方法参数

编辑:我应该给出一个更好的例子来开始;让我们再试一次:

// MyAppComponentModel.dll 
namespace MyAppComponentModel { 
    using System.Collections; 

    interface IResource { } 
    interface IStringResource : IResource { } 
    interface IIconResource : IResource { } 
    interface IDialogResource : IResource { } 
    interface IResourceProvider { 
    void GetResource<T>(out T result, IDictionary criteria = null) where T : IResource; 
    } 
} 

// ThirdPartyLib.dll 
namespace ResourceProviderLibA { 
    using System.Collections; 
    using System.ComponentModel.Composition; 
    using MyAppComponentModel. 

    public sealed class StringResource : IStringResource { ... } 
    public sealed class IconResource : IIconResource { ... } 

    [Export(typeof(IResourceProvider))] 
    public sealed class StringAndIconResourceProvider : IResourceProvider { 
    void IResourceProvider.Get<T>(out T result, IDictionary criteria) { 
     if (typeof(T) == typeof(IDialogResource)) 
     throw new NotSupportedException(); 

     this.InternalGet(out result, criteria); 
    } 

    void InternalGet(out IStringResource result, IDictionary criteria) { 
     result = new StringResource(); 
     ... 
    } 

    void InternalGet(out IIconResource result, IDictionary criteria) { 
     result = new IconResource(); 
     ... 
    } 
    } 
} 

// MyMefTestApp.exe 
namespace MyMefTestApp { 
    using System.Collections.Generic; 
    using System.ComponentModel.Composition.Hosting; 
    using MyAppComponentModel. 

    static class Program { 
    [ImportMany(typeof(IResourceProvider))] 
    private IEnumerable<IResourceProvider> mProviders; 

    static void Main(String[] args) { 
     foreach (var provider in this.mProviders) { 
     ... 
     } 
    } 
    } 
} 

我知道这是在某种程度上可能的,我坚信我做了这样的事情曾经只是不记得如何。任何人?

我已经知道这可以通过反射完成,所以请跳过这些解决方案 - 谢谢。

回答

2

这是不可能的,因为T可以是任何东西(编译错误实际上是cannot convert from 'out T' to 'out string'),而不仅仅是一个stringint

刚刚露出privateFoo重载公共Foo并用它做,还有,你不能限制一个通用的stringint(两者都是密封的,泛型类型约束需要一个接口或非没有其他办法密封类)。

编辑(改变问题)

如果你的资源实现只有参数构造函数,我会用这个(浓缩为例):如果他们需要参数但是......唷

interface IHostProvider 
{ 
    void Get<T> (out T result) where T : IHost, new(); 
} 

public interface IHost 
{ 
} 

public class Something : IHost 
{ 
} 

public class Provider : IHostProvider 
{ 
    public void Get<T> (out T result) where T: IHost, new() 
    { 
     result = new T(); 
    } 
} 

,不知道这在深夜。起初我有一个静态工厂方法,但是因为你不能在接口中需要一个静态方法,也不能将其标记为抽象,这也不起作用。

+0

我已将示例代码更新为更实用的示例;请看看它,看看它是否以任何方式改变你的答案。我真的需要一些帮助,或者至少有一个“良好的编程”方式来解决这个问题。 – gplusplus 2011-02-13 00:39:58

0

您的示例在我看来不可能。编译器可以从已知的实际参数类型推断方法的类型参数。例如:

void DoSomething<T>(T item) 
{ 
    ... 
} 

IFoo foo = default(IFoo); 
DoSomething(foo); // void DoSomething<IFoo>(IFoo item); 

但编译器不能做相反的事情。编译器无法猜测T的实际类型,这就是为什么它不能选择适用的方法过载。

void DoSomething(IFoo foo) 
{ 
    ... 
} 

T item = default(T); 
DoSomething(item); // won't compile unless it is known that T is IFoo (where T : IFoo)