首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >C#为具有泛型方法的泛型类创建接口

C#为具有泛型方法的泛型类创建接口
EN

Stack Overflow用户
提问于 2013-05-09 16:38:26
回答 2查看 376关注 0票数 1

假设我有一段代码

代码语言:javascript
运行
复制
public interface IFoo
{
}

public abstract class FooBase<TModel> : IFoo
{
    public T Create<T>() where T : TModel;
}

public class Foo : FooBase<ModelBase>
{
    public TModel Create<TModel>()
    {
        return Activator.CreateInstance(typeof(TModel));
    }
}

public abstract class ModelBase
{
}

public class ModelFoo : ModelBase
{
}

public class ModelBar : ModelBase
{
}

现在,假设我有这样一个类

代码语言:javascript
运行
复制
public static FooProvider
{
    public IFoo Get<TModel>()
    {
        var provider = ...; // find which IFoo class has generic TModel
        return provider;
    }
}

我可以用下面的命令调用它

代码语言:javascript
运行
复制
IFoo provider = FooProvider.Get<ModelBar>();  // -> instance of Foo

但是我得到了IFoo的一个实例,因此不能访问FooBase方法。是否可以实现IFoo (或中间抽象类)来提供一个方法声明,该方法声明可以在不(必然)强制转换返回值provider的情况下调用

理想情况下,我希望能够做到

代码语言:javascript
运行
复制
ModelBar bar = FooProvider.Get<ModelBar>().Create<ModelBar>();

有可能吗?

EN

Stack Overflow用户

发布于 2013-05-09 16:54:58

你的意思是

代码语言:javascript
运行
复制
ModelBar bar = FooProvider.Get<ModelBar>().Create<ModelBar>();

或者更确切地说

代码语言:javascript
运行
复制
ModelBar bar = FooProvider.Get<ModelBar>().Create();

我觉得前者有点奇怪,除非在某些情况下,第一个ModelBar实际上是ModelBarBase或IModelBar,而后者ModelBar实际上是最后一个可构造的类型。

无论如何,我也发现您的类布局有点奇怪,因为在您的代码示例中,Get()和Create()来自同一个类(Foo/FooBase)。我觉得你把SRP搞砸了。

我会推荐:

代码语言:javascript
运行
复制
public class FooProvider
{
    public static Provider<T> Get<T> { return new Provider<T>(); };
}

public class Provider<T>
{
    public T CreateDirect()
    {
        return Activator.Create<T>();
    }

    public TDerived CreateDerived<TDerived>() where TDerived : T
    {
        return Activator.Create<TDerived>();
    }
}

在此设置中,您可以:

代码语言:javascript
运行
复制
class IMyInterf {}
class MyType : IMyInterf {}
class MyChildType : MyType {}

MyType tmp1 = FooProvider.Get<MyType>().CreateDirect();

MyChildType tmp1 = FooProvider.Get<MyType>().CreateDerived<MyChildType>();

MyChildType tmp1 = FooProvider.Get<IMyInterf>().CreateDerived<MyChildType>();

这只是一个草图,手写,没有编译,但它显示了一般的想法。

如果您删除"CreateDirect“并将"CreateDerived”重命名为just Create,您将得到类似于您的代码的内容,但更简单。当然,如果确实需要,您现在可以将这两个单独的类混合并压缩成一个类,但我看不出这有什么实际意义:)

编辑:

当然,您可以引入一个ProviderBase<T>和多个OrangeProvider:ProviderBase<Orange>,而不是Provider<T>,这只是为了更容易地构建/找到适当的提供者,但实际的Get<>仍然必须返回实际的ProviderBase<T>IProvider<T>

票数 1
EN
查看全部 2 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16457695

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档