有没有办法用reflection“覆盖”方法?

没有inheritance但只有reflection是否可以在C#中动态更改方法的代码?

就像是 :

nameSpaceA.Foo.method1 = aDelegate; 

我不能改变/编辑Foo类。

 namespace nameSpaceA { class Foo { private void method1() { // ... some Code } } } 

我的最终目标是改变动态代码:

 public static IList EnsureNodeSet(IList listItems); 

在System.Xml.Xsl.Runtime.XslConvert.cs中

转:

 if (!item.IsNode) throw new XslTransformException(Res.XPath_NodeSetExpected, string.Empty); 

进入:

 if (!item.IsNode) throw new XslTransformException(Res.XPath_NodeSetExpected, item.value); 

这个答案的第一部分是错误的,我只是留下它,以便评论中的演变是有道理的。 请参阅编辑。

你不是在寻找reflection,而是在发射(这是另一种方式)。

特别是,有一种方法可以满足你的需求,幸运的是你!

请参见TypeBuilder.DefineMethodOverride

编辑:
写下这个答案,我只记得重新混音也允许你这样做。 但这更难了。

重新混合是一个“模拟”C#中的mixin的框架。 在其基本方面,您可以将其视为具有默认实现的接口。 如果你走得更远,那就远不止于此。

编辑2:这是一个用于重新混合的例子(在不支持它的类上实现INotifyPropertyChanged,并且不知道mixin)。

 using System; using System.Collections.Generic; using System.Linq; using System.Text; using Remotion.Mixins; using System.ComponentModel; using MixinTest; [assembly: Mix(typeof(INPCTester), typeof(INotifyPropertyChangedMixin))] namespace MixinTest { //[Remotion.Mixins.CompleteInterface(typeof(INPCTester))] public interface ICustomINPC : INotifyPropertyChanged { void RaisePropertyChanged(string prop); } //[Extends(typeof(INPCTester))] public class INotifyPropertyChangedMixin : Mixin, ICustomINPC { public event PropertyChangedEventHandler PropertyChanged; public void RaisePropertyChanged(string prop) { PropertyChangedEventHandler handler = this.PropertyChanged; if (handler != null) { handler(this, new PropertyChangedEventArgs(prop)); } } } public class ImplementsINPCAttribute : UsesAttribute { public ImplementsINPCAttribute() : base(typeof(INotifyPropertyChangedMixin)) { } } //[ImplementsINPC] public class INPCTester { private string m_Name; public string Name { get { return m_Name; } set { if (m_Name != value) { m_Name = value; ((ICustomINPC)this).RaisePropertyChanged("Name"); } } } } public class INPCTestWithoutMixin : ICustomINPC { private string m_Name; public string Name { get { return m_Name; } set { if (m_Name != value) { m_Name = value; this.RaisePropertyChanged("Name"); } } } public void RaisePropertyChanged(string prop) { PropertyChangedEventHandler handler = this.PropertyChanged; if (handler != null) { handler(this, new PropertyChangedEventArgs(prop)); } } public event PropertyChangedEventHandler PropertyChanged; } } 

而且测试:

 static void INPCImplementation() { Console.WriteLine("INPC implementation and usage"); var inpc = ObjectFactory.Create(ParamList.Empty); Console.WriteLine("The resulting object is castable as INPC: " + (inpc is INotifyPropertyChanged)); ((INotifyPropertyChanged)inpc).PropertyChanged += inpc_PropertyChanged; inpc.Name = "New name!"; ((INotifyPropertyChanged)inpc).PropertyChanged -= inpc_PropertyChanged; Console.WriteLine(); } static void inpc_PropertyChanged(object sender, PropertyChangedEventArgs e) { Console.WriteLine("Hello, world! Property's name: " + e.PropertyName); } //OUTPUT: //INPC implementation and usage //The resulting object is castable as INPC: True //Hello, world! Property's name: Name 

请注意:

 [assembly: Mix(typeof(INPCTester), typeof(INotifyPropertyChangedMixin))] 

 [Extends(typeof(INPCTester))] //commented out in my example 

 [ImplementsINPC] //commented out in my example 

有完全相同的效果。 这是您希望定义特定mixin应用于特定类的位置的问题。

示例2:重写Equals和GetHashCode

 public class EquatableByValuesMixin<[BindToTargetType]T> : Mixin, IEquatable where T : class { private static readonly FieldInfo[] m_TargetFields = typeof(T).GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); bool IEquatable.Equals(T other) { if (other == null) return false; if (Target.GetType() != other.GetType()) return false; for (int i = 0; i < m_TargetFields.Length; i++) { object thisFieldValue = m_TargetFields[i].GetValue(Target); object otherFieldValue = m_TargetFields[i].GetValue(other); if (!Equals(thisFieldValue, otherFieldValue)) return false; } return true; } [OverrideTarget] public new bool Equals(object other) { return ((IEquatable)this).Equals(other as T); } [OverrideTarget] public new int GetHashCode() { int i = 0; foreach (FieldInfo f in m_TargetFields) i ^= f.GetValue(Target).GetHashCode(); return i; } } public class EquatableByValuesAttribute : UsesAttribute { public EquatableByValuesAttribute() : base(typeof(EquatableByValuesMixin<>)) { } } 

这个例子是我实施的重新混合动手实验室。 你可以在那里找到更多信息。

    Interesting Posts