首页 > 解决方案 > 创建将在 .net 核心中返回通用抽象类型对象的工厂

问题描述

我正在创建使用抽象泛型类作为基础的代码。我有点卡住了,因为我试图创建将根据插入的对象类型返回特定对象的工厂。

可以说我想与对象进行比较以检查它们是否相等。在我的场景中,如果它们是IEnumerableIList

我的代码:

界面 :

public interface IObjectComparer<in T>
{
    bool Compare(T obj1, T obj2);
}

基类:

public abstract class ObjectComparerBase<T> : IObjectComparer<T>
{
    public abstract bool Compare(T obj1, T obj2);

    public void SomeUsefullHelperMethod()
    {

    }
}

IList对象比较器:

public sealed class ListObjectComparer : ObjectComparerBase<IList>
{
    public override bool Compare(IList obj1, IList obj2)
    {
        throw new NotImplementedException();
    }
}

IEnumerable对象比较器

public sealed class EnumerableObjectComparer : ObjectComparerBase<IEnumerable>
{ 
    public override bool Compare(IEnumerable obj1, IEnumerable obj2)
    {
        throw new System.NotImplementedException();
    }
}

最后,我的工厂应该决定是否需要对某个对象使用哪个比较器:

public sealed class ComparerRetriever
{
    public static IObjectComparer<T> Retrieve<T>(T obj)
    {
        IObjectComparer<T> comparer = null;
        switch (typeof(T))
        {
            case IEnumerable o:
            {
                comparer = new EnumerableObjectComparer();
                break;
            }

            case IList o:
            {
                comparer = new ListObjectComparer();
                break;
            }

            default:
                throw new NotSupportedException("Not Supported Type");
        }

        return comparer;
    }
}

我的问题 :

在当前情况下,我无法使用我的ComparerRetriever课程,因为编译器说那ListObjectComparer也不 EnumerableObjectComparerIObjectComparer<T>类型。

我的问题是为什么?我的对象有ObjectComparerBase<T>一个类作为父类,这个类IObjectComparer<T>在我看来是这样实现的EnumerableObjectComparerListObjectComparer应该是ObjectComparerBase<T>

可能我错过了一些东西,但在这一点上我看不到什么。

你能帮助我吗 ?

谢谢。

标签: c#generics.net-core

解决方案


所以这可以正常工作并按预期返回类。您必须将 IList 放在首位,因为 IList 实现 IEnumerable 并且如果 IEnumerable 是第一个,它也将属于这种情况。

public sealed class ComparerRetriever
{
    public static IObjectComparer<T> Retrieve<T>(T obj)
    {
        IObjectComparer<T> comparer;
        switch (typeof(T))
        {
            case IList o:
            {
                comparer = new ListObjectComparer() as IObjectComparer<T>;
                break;
            }
            case IEnumerable o:
            {
                comparer = new EnumerableObjectComparer() as IObjectComparer<T>;
                break;
            }


            default:
                throw new NotSupportedException("Not Supported Type");
        }

        return comparer;
    }
}

我确实认为,尽管您将始终按默认情况作为传递给该Retrieve方法的任何对象,因为它将具有具体类型,并且typeof将导致该具体类型而不是 Intreface

例如,当我进行测试时,我创建了

class SimpleList : IList
{
   ... blah
}

并且可以预见的typeof调用导致 SimpleList 而不是 IList 所以它总是抛出

NotSupportedException("Not Supported Type");

显然我可能是错的,你可能比我领先一步,所以我将把答案留在那里,因为我相信我已经回答了最初的问题

更新经过更多测试后,我不确定您是否可以在接口上使用模式匹配,因此我已将实现更改为以下内容,并且仍然使用默认情况。

public static IObjectComparer<T> Retrieve<T>(T obj)
{
    IObjectComparer<T> comparer;

    var interf = typeof(T).GetInterfaces().FirstOrDefault();
    switch (interf)
    {
        case IList o:
        {
            comparer = new ListObjectComparer() as IObjectComparer<T>;
            break;
        }
        case IEnumerable o:
        {
            comparer = new EnumerableObjectComparer() as IObjectComparer<T>;
            break;
        }


        default:
            throw new NotSupportedException("Not Supported Type");
    }

    return comparer;
}

推荐阅读