首先,我知道标题不是那么好但事情是我甚至不知道如何解释我的问题;我将在下面展示一下我正在尝试做的事情:
编辑:我本来应该给出一个更好的例子;让我们再试一次:
// 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) {
...
}
}
}
}
我知道这在某种程度上是可能的,我坚信我曾经做过类似的事情。任何人吗?
我已经知道这可以通过Reflection完成,所以请跳过这些解决方案 - 谢谢。
答案 0 :(得分:2)
这是不可能的,因为T
可以是任何内容(编译器错误实际上是cannot convert from 'out T' to 'out string'
),而不仅仅是string
或int
。
只需将privateFoo
重载公开为公开Foo
并完成,没有其他办法,因为您无法将通用限制为string
或int
(两者都是密封的,泛型类型约束需要接口或非密封类)。
编辑(已更改的问题)
如果您的Resource实现只有无参数构造函数,我会使用它(精简示例):
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();
}
}
如果他们需要参数但是... phew,不知道这个深夜。起初我考虑过静态工厂方法,但由于您不能在接口中使用静态方法,也不能将其标记为抽象,这也不起作用。
答案 1 :(得分: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)