猿问

C# 8默认接口实现和继承

我想使用 C# 8 默认接口实现来解决代码中的性能问题。


实际上,我有这个界面:


public interface IDataAdapter {}

public interface IDataAdapter<T> : IDataAdapter

{

   void Insert(T value);

}

实际上,我必须对所有对象进行反射IDataAdapter,检查泛型类型并Insert通过反射调用特定的 T 实例。我想做的是:


public interface IDataAdapter 

{

   void InsertValue(object value);

}

public interface IDataAdapter<T> : IDataAdapter

{

   void Insert(T value); 

   public void InsertValue(object value) => Insert(value as T);

}

编译器建议使用关键字 new 来屏蔽继承的方法。然而,我想要完成的唯一一件事是已经实现了一个非通用方法,以使所有IDataAdapter<T>实现只需实现通用版本。


这是我可以完成的事情还是仍然不可能?我已经知道使用抽象类是解决这个问题的一种方法,但我想让开发人员拥有一个实现许多 IDataAdapter 的类...


这是我当前的反射代码:


public IEnumerable<IDataAdapter> DataAdapters { get; }


    public Repository(IEnumerable<IDataAdapter> dataAdapters)

    {

        DataAdapters = dataAdapters;

    }


    public async Task SaveAsync()

    {

        foreach (var item in aggregates)

        {

            foreach (var dataAdapter in DataAdapters)

            {

                if (dataAdapter.GetType().GetInterfaces().Any(i => i.IsGenericType && i.GetGenericArguments()[0] == item.GetType()))

                {

                    dataAdapter.GetType().GetMethod("Insert", new[] { item.GetType() }).Invoke(dataAdapter, new[] { item });

                }

            }


        }

    }


慕虎7371278
浏览 86回答 1
1回答

RISEBY

从面向对象的角度来看,你想要做的事情是无法完成的。假设您创建以下类层次结构:public interface  IFoo{}public interface  IBar{}public class A: IFoo{}public class B: IFoo{}public class C:IFoo,IBar {}然后是以下适配器:public class TestA : IDataAdapter<A>{}public class TestB : IDataAdapter<B>{}public class TestC : IDataAdapter<C>{}public class TestIFoo : IDataAdapter<IFoo>{}public class TestIBar : IDataAdapter<IBar>{}public class TestIBoth : IDataAdapter<IFoo>,IDataAdapter<IBar>{}如果 TestA 收到 A 的实例,会发生什么很容易。但是 TestIFoo 获得 C 又如何呢?目前,您的反射代码将无法工作,因为您测试了类型相等性(C 等于 IFoo 吗?不!即使 C as IFoo 没问题)。这打破了里氏替换原则。如果某个东西适用于某个类,那么它也应该适用于它的任何子类。假设您解决了上述问题。现在 TestIBoth 获得 C 怎么样?其中是否有两种不同的 Insert 实现?当然,这是继承所必需的!但是……你必须插入 C 两次吗?还是必须在第一种安装方法中只插入一次?之所以要经过反思,是因为所有这些问题都需要一个算法的答案。你的编译器将无法回答(这使得语言顺便阻止它)
随时随地看视频慕课网APP
我要回答