2

I have lots of sub classes, inherited from IDbTypeHandler<T>, and I want know how to convert "SetValue" to lambda expression, after that I can call Action<IDbDataParameter, object>.

inteface

    public interface IDbTypeHandler
    {
    }
    public interface IDbTypeHandler<T> : IDbTypeHandler
    {
        void SetValue(IDbDataParameter parameter, T value);
    }

classes

    internal class UniqueidentifierUlIdHandler : IDbTypeHandler<UlId>
    {
        public void SetValue(IDbDataParameter parameter, UlId value)
        {
            parameter.Value = value.ToByteArray();
        }
    }
    internal class Char1Handler : IDbTypeHandler<bool>
    {
        public void SetValue(IDbDataParameter parameter, bool value)
        {
            parameter.Value = value;
        }
    }

---------------update------------------

the follow code is where i want to make a lambda expression

if (!TryGetValue("Key", out IDbTypeHandler dbTypeHandler))
{
   return false;
}

var t = dbTypeHandler.GetType();
var itf = t.GetInterfaces().SingleOrDefault(i => i.IsGenericType);
var xx = itf.GenericTypeArguments[0];

var p0 = Expression.Parameter(t);
var p1 = Expression.Parameter(typeof(IDbDataParameter));
var p2 = Expression.Parameter(xx);
var method = t.GetMethod("SetValue");
Type delegateType = typeof(Action<,,>).MakeGenericType(t, typeof(IDbDataParameter), xx);
var lambda = Expression.Lambda(delegateType, Expression.Call(p0, method, p1, p2), new[] { p0, p1, p2 });

now, i get a lambda. if i use .Compile(), then it will return a Delegate type. But, i want a Action<IDbDataParameter,object>

I know i need a type convert before var lambda = Expression.Lambda, but i don't know what to do for now.

goldii
  • 242
  • 2
  • 18
  • C# is a language of types. You don't show enough code to fix your `Expression` creation - where did `TryGetValue` come from? Why does your `Action` in your text only have two parameter types when you are building an expression with 3 types? – NetMage Apr 24 '23 at 17:46

1 Answers1

0

I have recreated a little sample with 2 ways to implement lambda (see classes test1 and test2)

internal class Program
{
    static void Main(string[] args)
    {
        var one = new One();
        var two = new Two();

        var obj_int = new ClassX();
        var obj_str = new ClassX();

        var ActOne = new test1<int, One>();
        var ActTwo = new test1<string, Two>();

        ActOne.myLambda1(obj_int, 10, one);
        ActTwo.myLambda1(obj_str, "Youpi", two);

        Console.WriteLine($"one = {obj_int.Value} two = {string.Join(",",(char[])obj_str.Value)}");

        new test2<int, One>().myLambda2(obj_int, 20);
        new test2<string, Two>().myLambda2(obj_str, "Super");

        Console.WriteLine($"one = {obj_int.Value} two = {string.Join(",", (char[])obj_str.Value)}");
    }

}
//lambda with U instantiated
public class test1<T,U> where U : ITest<T>
{
    public Action<ClassX, T, U> myLambda1 = (arg1, arg2, arg3) =>
    {
        arg3.SetValue(arg1, arg2);
    };
}
//lambda with U not instantiated
public class test2<T, U> where U : ITest<T> , new()
{ 
    public Action<ClassX, T> myLambda2 = (arg1, arg2) =>
    {
        new U().SetValue(arg1, arg2);
    };
}

public class ClassX
{
    public object Value;
}

public interface ITest<T>
{
    void SetValue(ClassX parameter, T value);
}
public class One : ITest<int>
{
    public void SetValue(ClassX parameter, int value)
    {
        parameter.Value = value + 10;
    }
}

public class Two : ITest<string>
{
    public void SetValue(ClassX parameter, string value)
    {
        parameter.Value = value.ToCharArray();
    }
}

result:

one = 20 two = Y,o,u,p,i
one = 30 two = S,u,p,e,r
Frenchy
  • 16,386
  • 3
  • 16
  • 39
  • Thanks for replay. there is one thing. maybe ,i have another class classB : ITest or class classC : ITest , and so on . in this case , Action the type "UlId" should be a generate type – goldii Apr 22 '23 at 15:35
  • all genric type have the extension toByteArray()? – Frenchy Apr 22 '23 at 16:09
  • and could you show ITest ? – Frenchy Apr 22 '23 at 16:23
  • @goldii i have modify my answer .. i dunno if i approach what you want.. – Frenchy Apr 22 '23 at 20:41
  • thanks for kind help. but i want use expression lambda. as i said , i had lots of sub classes , inherited from IDbTypeHandler. i have updated more code example. – goldii Apr 23 '23 at 14:03