是否有一种不可知的方法将派生类强制转换回基类而不指定基类?

时间:2011-11-02 00:24:32

标签: c# .net inheritance casting

因为在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);

我对此感到好奇,因为我希望能够在不知道基类的情况下做到这一点,例如在运行时。

3 个答案:

答案 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)

根据您尝试解决的问题(例如,阻止所有控件接受用户输入,根据控件实现进行不同的处理),您最好的选择是为所需单元创建和实现接口工作。

我们在应用程序中广泛使用接口,因此我们不必担心给定控件如何实现我们需要的功能。它需要更多的配置,但从长远来看,这是值得的。