使用覆盖初始化对象

时间:2013-02-14 16:39:10

标签: c#

是否可以用一些等效的覆盖来代替new运算符来初始化一个对象?

说我有一些对象,我想将它转换为某种派生类型。 让我们称它们为objBase和objDerived。

假设这个objDerived类型有一个方法,它在objBase方法上使用new修饰符,但我想在我的cast objBase对象中使用new方法。 有没有办法说出相同的东西:

objBase myObjB = new objBase();
myObjB = *override* objDervied();

也许没有理由想要这样做或者有一些非常简单的替代方案我不知道?我很确定一些人为的例子可以显示一段时间,虽然它可能有用...... 我实际上并不需要这样做,但自从我在方法中了解了新的修饰符关键字以来,我只是想知道它。

4 个答案:

答案 0 :(得分:2)

在这种情况下,无需覆盖。您始终可以直接将派生对象引用分配给基类变量:

objBase myObjB = new objDerived();

请注意,创建实例并立即重新分配也不是一个好习惯:

// Don't instantiate an object in the first line here, 
// since you're going to assign it in the next line
objBase myObjB;  //= new objBase();
myObjB = new objDervied();

至于:

  

假设这个objDerived类型有一个方法,它在objBase方法上使用new修饰符,但我想在我的cast objBase对象中使用new方法。

您只能通过分配或回送到派生类来调用隐藏基类方法的new方法:

objBase myObjB = new objDerived();
((objDerived)myObjB).Method(); // Will call objDerived.Method

如果myObjB实际上没有引用objDerived实例,则会在运行时失败。

此处的另一个选项是使用dynamic。对变量使用dynamic将导致动态调度发生,这将使变量有效地表现得好像它始终是“最派生”类型,并调用新方法。这实际上很有用,因为你可以在C#中有效地执行multiple dispatching,即使它通常是静态类型的。这是一个完整的工作样本:

void Main()
{
    Base b = new Derived();  
    dynamic d = b;
    Console.WriteLine(d.Output());//This prints "Derived"
}

public class Base {
public string Output() {
        return "Base";
}
}

public class Derived:  Base {
    public new string Output() {
        return "Derived";
}
}

答案 1 :(得分:1)

objBase myObjB = new objDervied();

答案 2 :(得分:1)

没办法!

您无法在运行时覆盖成员。

这将是动态语言的一个特性,而不是像C#这样的静态类型和编译语言。例如,您可以在JavaScript中执行此操作,因为您可以在运行时重用标识符:

var someJsObject = { myMethod: function() { } };
someJsObject.myMethod = function() { alert("hey, I did it!"); };

顺便说一下,我觉得这不是一个好习惯,因为有一件事是动态语言(鸭子打字)而另一件事是“嘿,我是鸭子,我曾经说 quack quack 但是现在我是一个咆哮的鸭子!“很遗憾。

更新

嗯...... 事实上你可以用C#和ExpandoObject来做这样的事情:

dynamic expando = new ExpandoObject();
expando.MyMethod = new Func<bool>(() => true);

dynamic expando2 = new ExpandoObject();
expando.MyMethod = new Func<string>(() => "What? I've changed!");

expando.MyMethod = expando2.MyMethod;

// This will set "What? I've changed!"
string result = expando.MyMethod();

但这仍然是一种不好的做法。

答案 3 :(得分:1)

  

所以假设这个objDerived类型有一个使用new修饰符的方法   在一个objBase方法,但我想使用我的演员新方法   objBase对象

你所要求的是我认为的这样的事情:

public class Base {
   public string Write() {
        return "Base";
   }
}

public class Derived:  Base {

    public new string Write() { //HIDES BASE CLASS METHOD
        return "Derived";
   }
}


void Main()
{
    Base b = new Derived();  
    b.Write();//THIS WILL RETURN "BASE"

    Derived d = new Derived();  
    d.Write();//THIS WILL RETURN "DERIVED"
}

无法这样做,因为派生类成员上的new会覆盖具体对象类型

要以您想要的方式工作,因此只使用基本类型,您需要使用基本的OOP概念,例如inheritancevirtual/absrtact方法。