我需要在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());
}
答案 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
这些对我来说都不是特别令人满意,但希望你能从中得到一些有用的东西......