【发布时间】:2017-05-21 13:58:45
【问题描述】:
我需要在 c#(TResult getter_Result) 中为 Task 的 Result 属性创建一个委托 我可以获取属性 Result 的 getter 方法
Resultgetter = (TaskGenericType).GetProperty("Result").GetGetMethod();
但要将其添加到 delegate ,以下是我的尝试。 我的尝试:
Delegate d = Delegate.CreateDelegate(typeof(MyDelegate), Resultgetter, true);
代表的签名是
public delegate object MyDelegate();
但这里的问题是:
我不能将“object”作为我的代表的回报,因为签名必须与 Result 属性匹配。
当我尝试编写 TResult 作为我的委托 (public 委托 TResult MyDelegate()) 的返回时,我收到 TResult 无法解析符号的错误。
如何为任务对象的getter_Result 创建委托。
我正在尝试做的事情: 1.获取Task对象Result的getter方法。并在一个事件完成后调用该吸气剂。
所以在那个过程中。 1我能够获得结果的吸气剂。但是当我因为参数不匹配而需要分配给委托时面临问题。因此,我需要了解如何为 Result 提供返回类型。
示例代码
有问题的代码行是
Delegate 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);
}
}
示例我如何获取“IsCompleted”属性
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());
}
【问题讨论】:
-
您可能需要使用
Type.MakeGenericType,但很难准确判断您仅使用 sn-ps 在做什么。请提供minimal reproducible example。 -
@JonSkeet :提供了我想要做什么的解释。谢谢
-
解释不是我要求的 - 我要求minimal reproducible example。当我们可以重现问题时,我们可以尝试修复它。
-
@JonSkeet 当然。添加了重现问题的示例代码。
-
好吧,目前您正在尝试为
Task<int>的Result属性创建一个返回类型为Task<string>的委托 - 该Result属性的类型只是@ 987654338@,不是Task的任何东西......
标签: c# .net task task-parallel-library