【发布时间】:2016-10-01 15:17:46
【问题描述】:
我将我的问题简化为一个小程序,其中举例说明了我在运行时收到的确切错误。
您可以将其复制粘贴到控制台应用程序中并亲自查看。
using System.Collections.Generic;
namespace ConsoleApplication5
{
class Program
{
static void Main(string[] args)
{
var list = new List<MyDataClass>()
{
new MyDataClass {A = 1, B = 1},
new MyDataClass {A = 3, B = 8}
};
var ops = new MyOperationsClass();
ops.ReallyGreatOperation(list, list[0]);
}
}
public class MyDataClass
{
public int A { get; set; }
public int B { get; set; }
public void AddDataPartsToEachOther()
{
var c = A + B;
A = c;
B = c;
}
}
public class MyOperationsClass
{
public void ReallyGreatOperation(object obj, object z)
{
dynamic x = obj;
if (x.Contains(z)) //<-- gets an error here..
((dynamic)z).AddDataPartsToEachOther();
}
}
}
那么真正的问题是什么?
据我了解,dynamic 关键字可以用作通配符,如果方法存在,它将毫无问题地被调用。那么为什么在这种情况下它对我不起作用?
现在,我知道我可以通过这样做来改变它:
public class MyOperationsClass
{
public void ReallyGreatOperation(object obj, object z)
{
dynamic x = obj;
// if (x.Contains(z)) //<-- gets an error here..
// ((dynamic)z).AddDataPartsToEachOther();
if (x.GetType().GetMethod("Contains").Invoke(obj, new[] {z}))
((dynamic)z).AddDataPartsToEachOther();
}
}
但正如我所说 - 我希望了解为什么更“自然”的方式不起作用..因为如果我这样做是别无选择的第二种方式 - 我看不出dynamic的意义不再是语言。
收到的实际错误:
System.Core.dll 中出现“Microsoft.CSharp.RuntimeBinder.RuntimeBinderException”类型的未处理异常
附加信息:'System.Collections.Generic.List.Contains(ConsoleApplication5.MyDataClass)' 的最佳重载方法匹配有一些无效参数
对于那些可能觉得相关的人,我添加了我的实际代码的 sn-p:
case RelationNavigation.RelationNavigationMultiplicity.ManyToOne:
{
var stringValue = dto.PropertiesData[relationNavigation.PropertyEnd.PropertyInfo.Name];
if (string.IsNullOrEmpty(stringValue))
continue;
dynamic list = relationNavigation.PropertyEnd.PropertyInfo.GetValue(modelObj);
var relatedModelIds = stringValue.Split(',').Select(int.Parse).ToArray();
foreach (var relatedModelId in relatedModelIds)
{
var relatedModel = GetById(relationNavigation.PropertyEnd.RelatedType, relatedModelId);
if (relatedModel == null)
continue;
if(!list.GetType().GetMethod("Contains").Invoke(list, new[] { relatedModel }))
//if (!list.Contains(relatedModel))
list.Add(relatedModel);
relationNavigation.RelatedObjectPropertyEnd.PropertyInfo.SetValue(relatedModel, modelObj);
}
break;
}
谢谢。
【问题讨论】:
-
@sstan 将添加..
-
什么类型在运行时有 obj 和 z?我知道它不会被修复,只是当您遇到异常时这些类型的一个示例。
-
您可以在这里找到问题的解释:Method not being resolved for dynamic generic type。它还包括解决方案,即将
z转换为动态:if (x.Contains((dynamic)z))。但就其价值而言,最好尽可能寻找非动态解决方案。 -
我编辑了我的答案你看了吗? :)
标签: c# .net dynamic reflection