[英]C# - Returning an implementation when generic method type is an Interface
这就是我要使用的方式:
var fooStuff = _foo.DoBarStuff().GetFooStuff(id);
我想在调用DoBarStuff()时返回实现,以便可以调用GetFooStuff(id)来获取fooStuff。
public interface IFoo() : IBar
{
FooStuff GetFooStuff(int id);
}
public class Foo
{
public FooStuff GetFooStuff(int id)
{
// get fooStuff
return fooStuff;
}
}
public interface IBar
{
T DoBarStuff<T>();
}
public class Bar
{
public T DoBarStuff<T>()
{
// do bar stuff
return T;
}
}
T是任何接口,当“返回T”时; 被执行,我需要它的实现返回。 现在,我在“ return T;”下的T下收到此错误; 线。
T是一种类型,在给定的上下文中无效。 类型参数名称此时无效。
谢谢!
这应该工作:
public interface IBar
{
T DoBarStuff<T>() where T : class, new();
}
public class Bar : IBar
{
public T DoBarStuff<T>() where T : class, new()
{
// do bar stuff
return new T();
}
}
但是,使用方法DoBarStuff
时必须指定类型:
用法: var fooStuff = _foo.DoBarStuff<FooWhatEver>().GetFooStuff(id)
如果您不想这样做,请使用您的类/接口泛型:
public interface IBar<T> where T : class, new()
{
T DoBarStuff<T>();
}
public class Bar<T> : IBar<T> where T : class, new()
{
public T DoBarStuff()
{
// do bar stuff
return new T();
}
}
用法:
IBar bar = new Bar<FooWhatEver>();
var fooStuff = _foo.DoBarStuff().GetFooStuff(id);
但是所有这些都不适用于接口,仅适用于可实例化的类(具有默认构造函数)。
对于接口,您将需要一些东西来在它们及其实现之间进行转换。
简单的方法是使用字典(出于测试目的,但是您可以按照@N_tro_P的建议使用依赖项注入框架,即使现在在其中之一之间进行选择也不应该成为您的主要目标)。
您最终会得到这样的结果(不要忘记您的继承和通用部分):
public class Bar // <T> or not depending on your choice
// You can add this constraint to avoid value types (as int):
// where T : class
{
Dictionary<Type, Type> _container = new Dictionary<Type, Type>();
{
{typeof(IFoo), typeof(Foo)}
};
public T DoBarStuff() // <T> or not depending on your choice
// You can add this constraint to avoid value types (as int):
// where T : class
{
// get fooStuff
return Activator.CreateInstance(_container[typeof(T)]);
// You will get an error if T is not in the container
// or if _container[typeof(T)] is not instantiable
// or doesn't have a default constructor.
}
}
唯一的问题是,您将必须用要使用的所有接口/类填充字典/容器,处理起来会很烦人。 您可能希望使用我的第一种解决方案。
您可以执行此操作,但不能执行写呼叫签名的方式。
您从来没有让Bar不使用IBar,而Foo将其用作接口。 所以你应该改变它。 您可能会混淆如何与界面进行交互。
调整后的代码
public interface IFoo
{
FooStuff GetFooStuff(int id);
}
public class Foo : IFoo
{
public FooStuff GetFooStuff(int id)
{
// get fooStuff
return fooStuff;
}
}
public interface IBar
{
T DoBarStuff<T>();
}
public class Bar : IBar
{
public T DoBarStuff<T>()
{
// do bar stuff
return container[typeof(T)];
}
}
您要使用的是确保您随后输入类型,例如这样。
var fooStuff = _foo.DoBarStuff<BarStuff>().GetFooStuff(id);
这就是依赖容器的工作方式。 他们在其中将使用类型作为键的实例化对象存储在Dictionary中。 即字典实例;
然后,您也可以将工厂存储在其他位置,但这需要您的符号匹配,或者您只是假设它们可以独立访问其依赖项,因此可以使用Dictionary>工厂;
总的来说,我将看一下依赖容器。 无论您从事什么工作,都可能只是将其作为一种模式而已,并且已经制作了许多内容,因此无需自己动手制作。 如果要按类型返回对象,则这是一个依赖容器。 另外,我建议通过注入,这样您就不会与容器耦合。 换句话说,将其包装在接口中,然后使用现成的(Unity,MEF等)
public interface IDependencyContainer
{
T Resolve<T>();
void Register<T>(T instance);
void Register<T>(Func<T> instance);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.