C# 避免冗余 - 将派生类型转换为基本泛型类型并访问公共 属性
C# avoid redundancy - convert derived type to base generic type and access common property
我刚开始使用 C#,在解决以下问题时遇到了一些困难。
上下文:
- 我有三个 classes(假设 A、B 和 C)共享一些属性。因此它们都是派生的 class 抽象 class MySuperClass.
es
- 类 A、B 和 C 包含一个名为 Values 的列表,它将根据 class A、B 和 C 包含特定类型的元素。对于每个 class,有存在另一个 class ValuesA、ValuesB 和 ValuesC 来明确列表值的内容。
- ValuesA、ValuesB 和 ValuesC 也共享一些属性,并且是从抽象 class MyGenericType
派生的 classes
这是抽象 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) { }
}
}
}
我刚开始使用 C#,在解决以下问题时遇到了一些困难。
上下文:
- 我有三个 classes(假设 A、B 和 C)共享一些属性。因此它们都是派生的 class 抽象 class MySuperClass. es
- 类 A、B 和 C 包含一个名为 Values 的列表,它将根据 class A、B 和 C 包含特定类型的元素。对于每个 class,有存在另一个 class ValuesA、ValuesB 和 ValuesC 来明确列表值的内容。
- ValuesA、ValuesB 和 ValuesC 也共享一些属性,并且是从抽象 class MyGenericType 派生的 classes
这是抽象 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) { }
}
}
}