我有两个对象:Obj
和ObjViewModel
。ObjViewModel
内部有一个方法,看起来像这样:
public static implicit operator ObjViewModel(Obj o)
{
//Code to do the conversion here
}
我后来有一个反射方法,最终遇到了需要将List<obj>
复制到List<objViewModel>
的情况。代码看起来像这样:
foreach(var p in propertyPairs)
{
if (p.ViewModel.PropertyType.GetInterfaces().Count(i => i.Name == "IList") > 0)
{
p.ViewModel.SetValue(ret, Activator.CreateInstance(p.ViewModel.PropertyType));
foreach (var v in (IList)p.Model.GetValue(m))
{
((IList)p.ViewModel.GetValue(ret)).Add(v);
}
}
else
p.ViewModel.SetValue(ret, p.Model.GetValue(m));
问题是,当我到达((IList)p.ViewModel.GetValue(ret)).Add(v);
时,隐式转换从未在v上调用,代码崩溃,因为v是obj
类型,列表正在寻找objViewModel
。有人知道怎么解决这个问题吗?
您有一个编译时类型(由于强制转换)非泛型IList
的表达式。非泛型IList
的Add
方法采用System.Object
。所以:
((IList)something).Add(v);
只需要将v
转换为System.Object
。因此c#编译器不会插入对用户定义转换的调用。
即使转换为implicit
,您也可以显式调用它,如:
((IList)something).Add((ObjViewModel)v);
另一种可能的工作(我不确定你在后台有什么类型)是:
((IList<ObjViewModel>)something).Add(v);
要求something
实际实现IList<ObjViewModel>
。这个Add
方法是另一个接受ObjViewModel
类型参数的方法,因此c#编译器将搜索并找到您的用户定义转换并发出在v
上调用它的IL代码。