C# 避免冗余 - 将派生类型转换为基本泛型类型并访问公共 属性

C# avoid redundancy - convert derived type to base generic type and access common property

我刚开始使用 C#,在解决以下问题时遇到了一些困难。

上下文:

这是抽象 classes SuperClass 和 MyGenericType 的代码:

public abstract class SuperClass<T> where T : MyGenericType
{
    public SuperClass()
    {
         Values = new List<T>();
    }
    public List<T> Values {get; set;}

    //some other properties 
}
public abstract class MyGenericType
{
    public int property1 {get; set;}
    public int property2 {get; set;}
}

这是 class A 和 ValuesA 的代码: (NB class B (resp. C) 和 ValuesB (resp. ValuesC) 具有相同的模板,仅属性更改(例如 propertyA1 或 propertyValuesA1)

public class A : SuperClass<AListValuesType>
{
    public A()
    {
        Values = new List<ValuesA>();
    }
    public int propertyA1 {get; set;}
    public bool propertyA2 {get; set;}
}

public class ValuesA : MyGenericType
{
    public bool propertyValuesA1;
    //some other properties
}

问题:在我的过程中,我有三个类型为 A、B 和 C 的对象(可在我的所有 ScriptMain class 中访问),其中应用了大致相同的转换。为了避免冗余,我想在某些时候使用一个公共局部变量来存储类型 A、B 和 C 的对象,并像使用任何类型 A、B 或 C 的对象一样使用它。

这是我仅使用对象 A 的示例,我需要对对象 B 和 C 执行完全相同的操作。

public class ScriptMain
{
    private A apiResultA;
    private B apiResultB;
    private C apiResultC;

    //some stuff

    public bool NextRow(string request)
    {
        //I would like to be able to have a variable apiResult that could store either apiResultA, apiResultB or apiResultC according to request value
        if (apiResultA != null)
        {
            //Need to be able to check if apiResultA.Values.Count=0
            //lot of generic stuff working for apiResultA, apiResultB and apiResultC
        }
        else
        {
            //lot of generic stuff working for apiResultA, apiResultB and apiResultC
        }
    }
}

我已经尝试转换我的变量,使用接口...但我无法解决我的问题,我不知道下一步该去哪里。

感谢您阅读本文!

您可以使用具有协方差的接口(out T):

public interface ISuperClass<out T> where T : MyGenericType
{
    IEnumerable<T> ValuesEnumerator { get; }  // IList dosen't support covariance, we have to use IEnumerable
    // Some other properties in your SuperClass 
}

SuperClass 实现 ISuperClass:

public abstract class SuperClass<T> : ISuperClass<T> where T : MyGenericType
{
    public SuperClass()
    {
        Values = new List<T>();
    }
    public List<T> Values { get; set; }
    public  IEnumerable<T> ValuesEnumerator => Values;
}

现在您可以将结果转换为 ISuperClass:

public class ScriptMain
{
    private A apiResultA;
    private B apiResultB;
    private C apiResultC;

    //some stuff

    public bool NextRow(string request)
    {
        ISuperClass<MyGenericType> result = apiResultA;   // ISuperClass is covariant, so you can cast SuperClass<ValuesA> to ISuperClass<MyGenericType>
        if (result != null)
        {
            if (result.ValuesEnumerator.Count() == 0) { }
        }
    }
}