C#覆盖/向对象添加方法/字段

我有一个为我创建和设置对象的库,然后我可以使用这些对象来做东西。

假设我给了“A”类对象“a”

所以我想覆盖该特定对象中的方法,我不想更改其类的代码,因为这需要更改库。

在Ruby中我可以使用Singleton Classes来做到这一点,例如:

class FirstClass def test p "test" end end o = FirstClass.new class << o def test p "overridden" end def extraMethod p "ok" end end o.test # prints "overridden" o.extraMethod 

现在我怎样才能在C#中做同样的事情?

更新

我最终没有使用我提交的答案,因为它太丑了,它需要更改基类中的所有私有字段以保护或公共以使它们存在于派生类中,因此我可以将值从base复制到派生。

我最终使用的方法是将从基类派生的Type传递给库并更改库,以便它使用以下命令创建实例:

 (A)Activator.CreateInstance(mytype, arguments); 

除了通过dynamic机制之外,C#不(直接)支持类型的运行时扩展。

最接近的选项可能是使用带dynamic ExpandoObject

 dynamic o = new ExpandoObject(); oa = 10; o.ExtraMethod = new Action( () => Console.WriteLine("ok") ); // Invoke o.ExtraMethod(); 

话虽这么说,这不是使用C#的典型方式。

通过使用Delegates,可以在C#中“覆盖方法”(注意引号)

 public class SomeClass { public SomeClass() { //set the default OverridableMethod = () => MessageBox.Show("Default!"); } public void StandardMethod() { //Call it. OverridableMethod(); } public Action OverridableMethod {get;set;} } 

用法:

 var some1 = new SomeClass(); some1.StandardMethod(); //Shows "Default!" some1.OverridableMethod(); //Shows "Default!" var some2 = new SomeClass {OverridableMethod = () => MessageBox.Show("Override!!")}; some2.StandardMethod(); //Shows "Override!" some2.OverridableMethod(); //Shows "Override!" 

实际上有一种丑陋的方式可以做到这一点。

我在考虑使用inheritance和向下转换,但是向下转换是无效的。 但是,您可以使用reflection来实现相同的结果。

 static void Main() { A a = new A(); a.FieldA = 999; // change the object a.test(); // "This is A and FieldA is 999" //B b = (B)a; // => Error: Invalid you cannot downcast ! // using reflection we turn "a" into an instance of B that is a copy of the old "a" a = new B(a); a.test(); // This will call the method in B: "Calling the new method" "This is B and FieldA is 999 and FieldB is 10" // a.newMethod(); => Error cannot access this method because "a" is declared as an instance of A (even though it's actually of B now) B b = (B)a; // Now downcasting works fine (because A is an instance of B actually) b.newMethod(); // works as expected: "This is B and FieldA is 999 and FieldB is 10" } class A { public int FieldA; public A() { FieldA = 100; } virtual public void test() { Console.WriteLine("This is A and FieldA is {0}", FieldA); } } class B : A { int FieldB; public B(A a) { // copy all fields foreach (FieldInfo pi in typeof(A).GetFields()) GetType().GetField(pi.Name).SetValue (this, pi.GetValue(a)); // add this field: FieldB = 10; } // We can override methods override public void test() { Console.WriteLine("Calling the new method:"); newMethod(); } // Add a new method but it will only be visible after casting A to B public void newMethod() { Console.WriteLine("This is B, FieldA is {0} and FieldB is {1}", FieldA, FieldB); } } 

所以我已经覆盖了“a”中的方法并为其添加了新的字段。

我意识到这与你在Ruby中可以做的不一样,但至少我可以覆盖方法并添加可以在我重写的方法中使用的方法/字段。