创建将在.net核心中返回通用抽象类型的对象的工厂

时间:2018-11-20 21:54:27

标签: c# generics .net-core

我正在创建使用抽象泛型类为基础的代码。因为尝试创建将根据插入的对象类型返回特定对象的工厂,所以我有些困惑。

让我们说我想与对象进行比较以检查它们是否相等。在我的场景中,如果对象是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类,因为编译器说ListObjectComparerEnumerableObjectComparer都不是IObjectComparer<T>类型。

我的问题是为什么?我的对象具有ObjectComparerBase<T>类作为父类,并且该类正在实现IObjectComparer<T>,因此我认为EnumerableObjectComparerListObjectComparer的类型应为ObjectComparerBase<T>

可能我缺少了一些东西,但是目前我看不到。

你能帮我吗?

谢谢。

1 个答案:

答案 0 :(得分:0)

因此这可以正常工作并按预期返回类。您必须将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将导致该具体类型而不是接口

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

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;
}