lundi 30 novembre 2020

MethodInfo.Invoke method with two ref parameters doesn't work [duplicate]

Bellow, you'll find a full running console program that is using Reflection to call a static "Sawpping References" method.

First you have a direct call to the static method, this one is working well. Second you have a invoke call to the same method...

namespace MethodInfoInvoke
{
  using System;
  using System.Globalization;
  using System.Reflection;

  public interface IMyClass<T>
  {
    int Id { get; set; }
    string Name { get; set; }
  }

  public class MyClass : IMyClass<MyClass>
  {
    #region Properties
    public int Id { get; set; } = -1;
    public string Name { get; set; } = default;
    #endregion

    public static void Swap(ref MyClass instance1, ref MyClass instance2)
    {
      MyClass instanceTmp = instance1;

      instance1 = instance2;
      instance2 = instanceTmp;
    }
    public override string ToString()
    {
      return string.Format(CultureInfo.InvariantCulture, "{0} (Id : {1} * Name : {2})", GetType(), Id, Name);
    }
  }

  class Program
  {
    public static void Test1()
    {
      MyClass i1 = new MyClass()
      {
        Id = 1,
        Name = "Name 1"
      };
      MyClass i2 = new MyClass()
      {
        Id = 2,
        Name = "Name 2"
      };

      Console.WriteLine("Test1\r\n\tBefore Swap ref\r\n\t\ti1 : {0}\r\n\t\ti2 : {1}", i1, i2);
      MyClass.Swap(ref i1, ref i2);
      Console.WriteLine("\tAfter Swap ref\r\n\t\ti1 : {0}\r\n\t\ti2 : {1}\r\n", i1, i2);
    }

    public static void Test2<T>() where T : IMyClass<T>, new()
    {
      T i1 = new T()
      {
        Id = 1,
        Name = "Name 1"
      };
      T i2 = new T()
      {
        Id = 2,
        Name = "Name 2"
      };

      Console.WriteLine("Test2\r\n\tBefore Swap ref\r\n\t\ti1 : {0}\r\n\t\ti2 : {1}", i1, i2);
      //
      // ?????????? Here is the problem ! Are references bad ???????
      MethodInfo method = typeof(T).GetMethod("Swap", BindingFlags.Static | BindingFlags.Public | BindingFlags.InvokeMethod);
      object[] parameters = { i1, i2 };
      method.Invoke(null, parameters);
      //
      //
      Console.WriteLine("\tAfter Swap ref\r\n\t\ti1 : {0}\r\n\t\ti2 : {1}\r\n", i1, i2);
    }

    static void Main(string[] args)
    {
      Test1();
      Test2<MyClass>();
      Console.ReadLine();
    }
  }
}

The goal is to create a "generic" unit test that can be call for all object inheriting from "MyClass".

Thx for your return (and solution :-) ) and sorry for my bad English.





Aucun commentaire:

Enregistrer un commentaire