如何在任务c#中为Result属性getter创建委托

时间:2017-05-21 13:58:46

标签: c# .net task task-parallel-library

我需要在c#中创建Task的Result属性的委托(TResult getter_Result) 我能够获得属性Result

的getter方法
Resultgetter = (TaskGenericType).GetProperty("Result").GetGetMethod();

但是要将此添加到委托中,以下是我的尝试。 我的尝试:

  Delegate d = Delegate.CreateDelegate(typeof(MyDelegate), Resultgetter, true);

代表的签名是

public delegate object MyDelegate();

但这里的问题是:  我不能拥有" object"作为我的委托的返回,因为签名必须与Result属性匹配。 当我尝试编写TResult作为我的委托(公共委托TResult MyDelegate())的返回时,我收到错误,即TResult无法解析符号。 如何为Task对象创建getter_Result的委托。

我想做什么: 1.获取Task对象的Getter getter方法。并在一个事件完成后调用该getter。

所以在这个过程中。 1我能够得到结果的吸气剂。但是由于参数不匹配我需要分配给委托时面临问题。因此,我需要了解如何为Result提供返回类型。

示例代码

有问题的代码行是

委托d = Delegate.CreateDelegate(typeof(MyDelegate),Resultgetter,true); 它会赶上那里,

catch中的堆栈跟踪是

System.ArgumentException: Cannot bind to the target method because its signature or security transparency is not compatible with that of the delegate type.
   at System.Delegate.CreateDelegate(Type type, MethodInfo method, Boolean throwOnBindFailure)
   at getProperties.Program.Main(String[] args) in Program.cs:line 126



using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;

public delegate Task<string> MyDelegate();


class Program
{


    static void Main(string[] args)
    {
        Task<int> task1 = Task<int>.Factory.StartNew(() => 1);
        int i = task1.Result;

        PropertyInfo[] vals = GetPublicProperties(task1.GetType());
        Type TaskGenericType = Type.GetType("System.Threading.Tasks.Task`1");
        MethodInfo Resultgetter;
        foreach (var x in vals)
        {
            if (x.ToString().Contains("Result"))
            {
                try
                {
                    Resultgetter = (TaskGenericType).GetProperty("Result").GetGetMethod();
                    ***Delegate d = Delegate.CreateDelegate(typeof(MyDelegate), Resultgetter, true);***
                }

                catch (Exception e)
                {

                    Console.WriteLine(e);
                    Console.WriteLine(e.StackTrace);
                    throw;
                }

            }
            Console.WriteLine(x.ToString());
        }


    }


    static PropertyInfo[] GetPublicProperties(Type type)
    {
        if (type.IsInterface)
        {
            var propertyInfos = new List<PropertyInfo>();

            var considered = new List<Type>();
            var queue = new Queue<Type>();
            considered.Add(type);
            queue.Enqueue(type);
            while (queue.Count > 0)
            {
                var subType = queue.Dequeue();
                foreach (var subInterface in subType.GetInterfaces())
                {
                    if (considered.Contains(subInterface)) continue;

                    considered.Add(subInterface);
                    queue.Enqueue(subInterface);
                }

                var typeProperties = subType.GetProperties(
                    BindingFlags.FlattenHierarchy
                    | BindingFlags.Public
                    | BindingFlags.Instance);

                var newPropertyInfos = typeProperties
                    .Where(x => !propertyInfos.Contains(x));

                propertyInfos.InsertRange(0, newPropertyInfos);
            }

            return propertyInfos.ToArray();
        }

        return type.GetProperties(BindingFlags.FlattenHierarchy
            | BindingFlags.Public | BindingFlags.Instance);
    }


}

示例我如何获取&#34; IsCompleted&#34;属性

 foreach (var x in vals)
            {
                if (x.ToString().Contains("IsCompleted"))
                {
                    try
                    {
                        Resultgetter = TaskType.GetProperty("IsCompleted").GetGetMethod();
                      //  Delegate d = Delegate.CreateDelegate(typeof(MyDelegate), Resultgetter, true);
                        Func<bool> testFunc = Delegate.CreateDelegate(typeof(Func<bool>), null, Resultgetter) as Func<bool>;

                        Console.WriteLine(10);
                    }

                     catch (Exception e)
                    {

                        Console.WriteLine(e);
                        Console.WriteLine(e.StackTrace);
                        throw;
                    }

                }
                Console.WriteLine(x.ToString());
            }

1 个答案:

答案 0 :(得分:0)

您可以通过表达式树来完成此操作,但是设置示例代码的方式使得它看起来像只是一个SelectedItem,这意味着任务必须已经嵌入在表达式树中。你可以这样做:

Func<object>

如果你想这样做,你也可以用反射调用using System; using System.Linq.Expressions; using System.Threading.Tasks; class Program { static void Main(string[] args) { Task<int> task = Task.FromResult(1); var constantExpression = Expression.Constant(task, task.GetType()); var propertyExpression = Expression.Property(constantExpression, "Result"); var conversion = Expression.Convert(propertyExpression, typeof(object)); var lambda = Expression.Lambda<Func<object>>(conversion); Func<object> compiled = lambda.Compile(); Console.WriteLine(compiled()); } } ,然后构建一个返回该代理的委托:

Result

这些对我来说都不是特别令人满意,但希望你能从中得到一些有用的东西......