Question

sans hériter mais seulement avec une réflexion, il est possible de modifier de manière dynamique le code d'une méthode en C #?

quelque chose comme:

nameSpaceA.Foo.method1 = aDelegate;

je ne peux pas changer / éditer la classe FOO.

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

Mon objectif final est de changer de dynamique le code de:

public static IList<XPathNavigator> EnsureNodeSet(IList<XPathItem> listItems);

dans system.xml.xsl.runtime.xslconvert.cs

Tourner:

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

dans:

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

Était-ce utile?

La solution

La première partie de cette réponse est fausse, je ne le quitte que pour que l'évolution dans les commentaires ait du sens. S'il vous plaît voir le (s) édition (s).

Vous ne cherchez pas de réflexion, mais l'émission (qui est l'inverse).

En particulier, il y a une méthode qui fait exactement ce que vous voulez, chanceux vous!

voir TypeBuilder.Definemethodoverride

edit:
Écrire cette réponse, je viens de me souvenir de cette
ré-mix vous permet de le faire aussi. C'est bien cependant.

Ré-mélangeur est un cadre qui "simule" les mélanges en C #. Dans son aspect de base, vous pouvez y penser comme des interfaces avec des implémentations par défaut. Si vous allez plus loin, cela devient beaucoup plus que ça.

edit 2: Voici un exemple d'utilisation pour ré-mélanger (mise en œuvre inotifypropertychangned sur une classe qui ne le supporte pas et n'a aucune idée de mixes).

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

et le test:

static void INPCImplementation()
        {
            Console.WriteLine("INPC implementation and usage");

            var inpc = ObjectFactory.Create<INPCTester>(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

Veuillez noter que:

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

et

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

et

[ImplementsINPC] //commented out in my example

avoir exactement le même effet. C'est une question de savoir où vous souhaitez définir qu'un mixin particulier est appliqué à une classe particulière.

Exemple 2: Remplacer les égaux et GetHashCode

public class EquatableByValuesMixin<[BindToTargetType]T> : Mixin<T>, IEquatable<T> where T : class
    {
        private static readonly FieldInfo[] m_TargetFields = typeof(T).GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

        bool IEquatable<T>.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<T>)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<>))
        {

        }
    }

Cet exemple est ma mise en œuvre du laboratoire pratique donné avec le ré-mélange. Vous pouvez trouver plus d'informations là-bas.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top