¿Hay alguna manera de “anular” un método con reflexión?

Sin heredar, pero solo con reflexión ¿es posible cambiar dinámicamente el código de un método en C #?

algo como :

nameSpaceA.Foo.method1 = aDelegate; 

No puedo cambiar / editar la clase Foo.

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

Mi objective final es cambiar dinámicamente el código de:

 public static IList EnsureNodeSet(IList listItems); 

En System.Xml.Xsl.Runtime.XslConvert.cs

a su vez:

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

dentro :

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

La primera parte de esta respuesta es incorrecta, solo la dejo para que la evolución en los comentarios tenga sentido. Por favor vea los EDIT (s).

No estás buscando la reflexión, sino la emisión (que es al revés).

En particular, hay un método que hace justo lo que quieres, ¡suerte!

Ver TypeBuilder.DefineMethodOverride

EDITAR:
Al escribir esta respuesta, acabo de recordar que el re-mix te permite hacer esto también. Aunque es mucho más difícil.

Re-mix es un marco que “simula” mixins en C #. En su aspecto básico, puede pensarlo como interfaces con implementaciones predeterminadas. Si vas más allá, se convierte en mucho más que eso.

EDIT 2: Aquí hay un ejemplo de uso para volver a mezclar (implementando INotifyPropertyChanged en una clase que no lo admite, y no tiene idea de mixins).

 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; } } 

Y la prueba:

 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 

Tenga en cuenta que:

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

y

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

y

 [ImplementsINPC] //commented out in my example 

Ten exactamente el mismo efecto. Es una cuestión de dónde desea definir que una mezcla particular se aplica a una clase particular.

Ejemplo 2: reemplazando Iguales y 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<>)) { } } 

Ese ejemplo es mi implementación del laboratorio práctico que se da con el re-mix. Puede encontrar más información allí.

Intereting Posts