Mic*_*ern 9 c# generics collections
在C#中,当泛型列表仅包含基类时,访问派生类的属性的最佳方法是什么.
public class ClassA : BaseClass
{
public object PropertyA { get; set; }
}
public class ClassB: BaseClass
{
public object PropertyB { get; set; }
}
public class BaseClass
{
}
public void Main
{
List<BaseClass> MyList = new List<BaseClass>();
ClassA a = new ClassA();
ClassB b = new ClassB();
MyList.Add(a);
MyList.Add(b);
for(int i = 0; i < MyList.Count; i++)
{
//I would like to access PropertyA abd PropertyB from the derived classes
}
}
Run Code Online (Sandbox Code Playgroud)
Mat*_*ton 19
当然你可以贬低,像这样:
for (int i = 0; i < MyList.Count; i++)
{
if (MyList[i] is ClassA)
{
var a = ((ClassA)MyList[i]).PropertyA;
// do stuff with a
}
if (MyList[i] is ClassB)
{
var b = ((ClassB)MyList[i]).PropertyB;
// do stuff with b
}
}
Run Code Online (Sandbox Code Playgroud)
...但是,你应该再看一下你想要完成的事情.如果您有需要获取ClassA和ClassB属性的公共代码,那么最好将对这些属性的访问包装到祖先类中的共享,虚拟属性或方法中.
就像是:
public class BaseClass
{
public virtual void DoStuff() { }
}
public class ClassA : BaseClass
{
public object PropertyA { get; set; }
public override void DoStuff()
{
// do stuff with PropertyA
}
}
public class ClassB : BaseClass
{
public object PropertyB { get; set; }
public override void DoStuff()
{
// do stuff with PropertyB
}
}
Run Code Online (Sandbox Code Playgroud)
继TimJ的答案之后,您可以编写一个适用于所有类型的扩展方法:
public static IEnumerable<T> OfType<T>(this IEnumerable list)
{
foreach (var obj in list)
{
if (obj is T)
yield return (T)obj;
}
}
Run Code Online (Sandbox Code Playgroud)
或者,如果您有Linq,该函数位于命名空间System.Linq中.