C#泛型抽象类和泛型方法

标签 c# .net oop

我在使用通用抽象类及其子类时遇到一些问题,并且我不知道如何解决。我有以下抽象类:

public abstract class Loader<T> where T: CommonPoco {
    public virtual List<T> LoadFromFile(StreamReader input, out List<T> result, bool trackProgress) {
        return LoadFromFile(input, out result, trackProgress, CultureInfo.CurrentCulture);
    }
    public abstract List<T> LoadFromFile(StreamReader input, out List<T> result, bool trackProgress, IFormatProvider format);
    public abstract T UploadToDb(List<T> data);
}

这是我的 CommonPoco:

public class CommonPoco {
    private int line;
    public int Line {
        get { return line; }
        set { line = value; }
    }

    private string error;
    public string Error {
        get { return error; }
        set { error = value; }
    }
}

现在我还有许多其他 Loader 子类,例如这个:

public class CountryLoader: Loader<Country> {
    public override List<Country> LoadFromFile(StreamReader input,
        out List<Country> result, bool trackProgress, IFormatProvider format) {
        //Method implementation
    }
    public override Country UploadToDb(List<Country> data) {
        //Method implementation
    }

我还有 CommonPoco 的许多子类,包括 Country 类。到目前为止,一切都很好。现在问题来了,我想实现一个通用的方法。此方法将根据某些参数,为任务使用正确的加载器。也许是这样的:

void LoadModule<T>(Module module) where T: CommonPoco {
    Loader<T> loader;
    switch (module) {
        case Module.Country:
            loader = new CountryLoader();
            break;
    }
}

这不起作用,编译器提示说它无法从 CountryLoader 转换为 Loader。我必须创建一个方法来加载每个模块,除了 Loader 类的初始化之外,它们的代码完全相同。我真的很讨厌重复的代码,所以我怎样才能实现这个目标?

忘了提及,使用 .NET Framework 4.0。 如果需要的话,我愿意改变任何需要的东西,甚至是我的抽象类。谢谢。 我想知道使用接口(interface)而不是抽象类是否可以让我做到这一点。

最佳答案

如果将抽象类转换为接口(interface),如下所示:

public interface ILoader<T> where T : CommonPoco
    {
        List<T> LoadFromFile(StreamReader input, out List<T> result, bool trackProgress);
        List<T> LoadFromFile(StreamReader input, out List<T> result, bool trackProgress, IFormatProvider format);
        T UploadToDb(List<T> data);
    }

然后更改您的 CountryLoader 实现:

public class CountryLoader : ILoader<Country>
    {
        public List<Country> LoadFromFile(StreamReader input, out List<Country> result, bool trackProgress)
        {
            return LoadFromFile(input, out result, trackProgress, CultureInfo.CurrentCulture);
        }

        public List<Country> LoadFromFile(StreamReader input,
            out List<Country> result, bool trackProgress, IFormatProvider format)
        {
            //Method implementation
            result = null;
            return null;
        }

        public Country UploadToDb(List<Country> data)
        {
            //Method implementation
            return null;
        }
    }

然后你创建一个像这样的方法:

void LoadModule<T>(Module module) where T:CommonPoco
        {
            ILoader<T> loader;
            switch (module)
            {
                case Module.Country:
                    loader = new CountryLoader() as ILoader<T>;
                    break;
            }
        }

这样做的问题是,您必须多次实现通用的 LoadFromFile,除非其他人有办法解决它。

关于C#泛型抽象类和泛型方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10555008/

相关文章:

c# - Linq 到 SQL : Why decimal field get truncated on Insert?

c# - 如何知道 EPSON TM-88IV 型热敏打印机上的纸张已用完

c# - Outlook 加载项部署

c# - 当属性不能为 null 时使用什么异常类型?

c# - 泛型、协变/逆变等

java - 如何从一个类调用另一个类的构造函数?

c# - tensorflow 服务

c# - VS2019 Docker 支持和 Dockerfile 失败

c# - EventSchemaTraceListener 的某些属性无法识别 app.config

php - 每个公共(public)属性都必须有访问器方法吗?