C# Pass by reference items in List<T>
本文关键字:lt gt List in Pass by reference items | 更新日期: 2023-09-27 18:19:56
在开发我的简单ORM时,我需要用它的代理替换POCO,所以我用ProxyBuilder编写了一些方法来处理POCO列表,以创建扩展POCO并实现IEntity的代理,然后用新的代理重新分配POCO对象,但在这样做的时候,我在POCO列表中重新分配项目后铸造对象时遇到了错误,它说"无法将Order类型的对象强制转换为IEntity类型的"
我用以下一些类来简化我的代码:
public class Order
{
public string Code { get; set; }
public string Description { get; set; }
public DateTime Date { get; set; }
public decimal Total { get; set; }
}
interface IEntity
{
public long ID;
}
public class OrderProxy : Order, IEntity
{
// some functions of a proxy
}
然后消费类似的代码
public void Run()
{
Order order1 = new Order() { .... };
Order order2 = new Order() { .... };
List<Order> orders = new List<Order>();
items.Add(order1);
items.Add(order2);
Process<Order>(orders);
// ERROR occured here 'Unable to cast object of type 'Order' to type 'IEntity'
((IEntity)order1).ID= 1;
}
public void Process<T>(List<T> items)
{
for (int i = 0; i < items.Count; i++)
{
items[i] = (T)CreateProxy();
}
}
private object CreateProxy(object obj)
{
// my ProxyBuilder will create new instance of OrderProxy depend on passed POCO parameter then return it
return new OrderProxy();
}
我知道List<>对于T是类,将通过引用传递,但在这种情况下,我不明白为什么它不能,处理后的列表变量orders包括我想要的代理,但order实例仍然不是代理,我可能错过了什么吗?或者任何人帮助我更改处理List<>的方式在我的代码中,提前感谢
问题是List本身实际上也只有引用。因此,在Process中,您将item[i]更改为不再指向Order的实例,而是指向OrderProxy的实例。
但这不会修改order1和order2,因为这两个没有指向特定的项目,而是指向项目(最初)引用的订单实例。更改引用的项目时,order1和order2不受此更改的影响,因为它们不指向项目,而是直接指向订单实例。
编辑:正如你补充的第二个问题。您的线路:
((IEntity)order1).ID= 1;
失败,因为IEntity用于ProxyOrder,但是order1属于Order类,并且将始终属于该类,并且该类不是派生IEntity的。因此,它不能自动转换为IEntity(如果你想这样做,你必须编写一个转换方法)。
调用Process后,您有四个不同的对象;
order1, order2, orders[0], orders[1]
订单1-订单[0]和订单2-订单[1]之间没有关系
您要查找的是订单[0]和订单[1]
因为您用其他类型(OrderProxy)替换了订单中的所有项目,所以order1
和orders[1]
现在是不同的对象。
尝试
((IEntity)orders[1]).ID = 1;
如果OrderProxy
像这个
class OrderProxy : Order
{
public Order Order {get;}
public OrderProxy(Order o)
{
this.Order = o;
}
}
您仍然可以通过访问原始订单1
((OrderProxy)orders[1]).Order
您试图抛出错误的东西,在调用Process之前,您有以下内容:
Order order1
Order order2
List<Order> orders
Order orders[0]
Order orders[1]
调用Process后,您将得到以下信息:
Order order1
Order order2
List<Order> orders
OrderProxy orders[0]
OrderProxy orders[1]
因此,为了将order1
转换为IEntity
,您需要通过列表中已"升级"为OrderProxy
的项目来执行此操作,因此您需要执行以下操作:
((IEntity)orders[0]).ID= 1;
不是
((IEntity)order1).ID= 1;