因为在C#中,类只能从单个类派生,有没有办法做类似的事情:
class Control
{}
class Button : Control
{}
class Slider : Control
{}
Button b = new Button();
Slider s = new Slider();
var base = (base) b;
var base2 = CastToBase(s);
我对此感到好奇,因为我希望能够在不知道基类的情况下做到这一点,例如在运行时。
答案 0 :(得分:2)
它们只能从单个类派生,但这并不意味着任何基类都不是从另一个基类派生的,除非它是System.Object
。如果您可以确定Base类(可以使用反射)并将其转换为基类(您可以使用反射),那么您在运行时会获得什么?
如果您试图访问派生类中不可用的基类方法/属性,则可能有一个很好的理由它在派生类型中不可用。如果您决定这样做,我认为您不需要强制转换它,您只需获取基类型,找到基类型的方法/属性并在派生类型上调用它们。
using System;
using System.Reflection;
namespace BaseTypetest
{
class Program
{
static void Main(string[] args)
{
BaseClass2 class2 = new BaseClass2();
Console.WriteLine(class2.Value.ToString());
Type baseClass = class2.GetType().BaseType;
Console.WriteLine(baseClass.FullName);
PropertyInfo info = baseClass.GetProperty("Value");
if (info != null)
{
Console.WriteLine(info.GetValue(class2, null).ToString());
}
Console.ReadKey();
}
}
public class BaseClass1 : Object
{
public BaseClass1()
{
this.Value = 1;
}
public int Value { get; set; }
}
public class BaseClass2 : BaseClass1
{
public BaseClass2()
{
this.Value = 2;
}
public new int Value { get; set; }
}
}
结果:
2
BaseTypetest.BaseClass1
1
答案 1 :(得分:2)
您可以通过反射获取对象的BaseType
:
something.GetType().BaseType
使用该Type
对象,您可以在运行时动态投射它。
但是,我强烈建议不要这样做。它会减慢你的代码,也没有编译器检查类型。
如果你需要将它放在IList<BaseType>
中,你就可以这样做了。
答案 2 :(得分:0)
根据您尝试解决的问题(例如,阻止所有控件接受用户输入,根据控件实现进行不同的处理),您最好的选择是为所需单元创建和实现接口工作。
我们在应用程序中广泛使用接口,因此我们不必担心给定控件如何实现我们需要的功能。它需要更多的配置,但从长远来看,这是值得的。