如何在分配基础对象时保留指定的对象属性?

时间:2013-05-01 14:14:44

标签: c# ruby generics object inheritance

好吧我回到另一个问题......看来当你将基础对象指定为另一个对象时,基础对象会变成那个对象,但仍然没有它的属性。

public class MyObjectBase {
        public void Begin() {

    }

{
public class OneOfMyObjects : MyObjectBase {
       public void Begin() {
       base.Begin();

   //do stuff

} 
} 
public class ManagmentClass {

public MyObjectBase myCurrentObject;

//called a only one when the program starts
public void Start() {
     Mymethod(new OneOfMyObjects()); 

}
//generic method 
public void Mymethod<T>(T Objectclass) where T : MyObjectBase {
        myObject = Objectclass
        myObject.Begin(); // compiler error, non existent in MyObjectBase 
        myObject.GetType().ToString() //returns "OneOfMyObjects" 

}
}

当然,编译器找不到“Begin()”,因为start最初并不存在于MyBaseObject中。 我正在进行类似于Ruby到C#的自定义语言之间的转换(上图),但这种类似Ruby的语言并没有遇到我遇到的这个“问题”。它似乎编译它。 .NET4中有什么东西可以解决我忘记的这个问题吗?

2 个答案:

答案 0 :(得分:2)

好吧,你可以只使用动态输入:

dynamic myObject;

...但是您的Mymethod方法无法真正接受MyObjectBase的任何实例...... 必须例如,Begin方法。使用动态类型,您只会发现执行时的情况并非如此。

您应该考虑代码尝试实现的更高级别目标,以及在C#中实现相同目标的最惯用方式,而不是直接移植为不同语言编写的某些代码。如果没有更多信息,我们无法为您提供指导。

答案 1 :(得分:1)

给它一个旋转。问题是你使用的是没有提供Begin定义的基类(你知道,只需重复)。因此,要做的是为基类提供一种具有Begin()方法的方法。在下面的示例中,MyObjectBase是一个抽象类,Begin()是一个抽象方法。这意味着MyObjectBase永远不会有Begin()的定义,但它会强制所有派生类为Begin()提供定义。所以,例如:

MyObjectBase obj1 = new MyObjectBase();
obj1.Begin(); //Won't Compile

OneOfMyObjects obj2 = new OneOfMyObjects();
obj2.Begin(); //Compiles if and only if OneOfMyObjects 
//class has a definition for Begin().

另外,我通常使用C ++编程,因此对于C#来说这可能不是100%最佳实践,但它是可编译的。我也改变了Begin的范围。当您希望派生类访问基类中的某些内容时使用受保护,但它不一定是您在处理派生的内容时使用的范围。从基础和派生类的外部访问Begin,因此需要公开。

public abstract class MyObjectBase
{
    public abstract void Begin();
}

public class OneOfMyObjects : MyObjectBase
{
    public override void Begin()
    {

        //do stuff

    }
}
public class ManagmentClass
{

    public MyObjectBase myCurrentObject;

    //called a only one when the program starts
    public void Start()
    {
        Mymethod(new OneOfMyObjects());

    }
    //generic method 
    public void Mymethod<T>(T Objectclass) where T : MyObjectBase {
    MyObjectBase myObject = Objectclass;
    myObject.Begin(); // Shouldn't throw an error any more
    myObject.GetType().ToString(); //returns "OneOfMyObjects" 

    }
}