我有一个基类Foo,它带有一个属性,用于标识数据库项中的主键。 其他类来自我的基类Foo,并包含这些类的特殊性的另一个属性。每个下降的类代表数据库中的一个不同的表。
通常,当加载这些数据时,这些项目存储在List< Foo>类型的相同列表中。
当我需要使用某个项目时,我会根据主键找到它。
当这些项目具有相同的主键时,我的问题就出现了,当从下层的类中查找项目时,FooB最终会找到一个类FooA,因为这是第一个,然后执行强制转换为FooB的地方会引发一个激活。 / p>
var list = new List<Foo>();
list.Add(new FooA() { PrimaryKey = 1 });
list.Add(nwe FooB() { PrimaryKey = 1 });
public Foo FindItem(int pk)
{
return list.First(it => it.PrimaryKey == 1);
}
在很多地方我使用这种方法根据我的需要找到我的项目。
var item = (FooB)FindItem(1);
在其他课程中:
var item = (FooA)FindItem(1);
在我的情况下,此代码用于系统中的许多位置,更改List&lt; Foo&gt;下降项目的列表是一个解决方案,但这意味着在许多地方进行更改,因为我无法在任何地方传递每个项目的类型。
我需要一个不会改变基本列表的解决方案。
答案 0 :(得分:3)
您需要重写FindItem(1)
方法,而不是返回Foo
的一个实例,而是返回一个特殊对象,该对象将同时包含FooA
个实例和PrimaryKey==1
以及{ {1}} FooB
的实例。
第二步是提供将此特殊对象转换为您需要的类型的强制转换操作符,以便代码PrimaryKey==1
按预期工作。
以下是实现此类解决方案的完全可用的代码。主要缺点是您必须为正在使用的每个派生类型提供强制转换操作符。您也可以从var item = (FooB)FindItem(1)
派生FooWrapper
(在这种情况下,Foo
只有一个属性会很简单,但这取决于您的实际Foo
类)
Foo
答案 1 :(得分:0)
public T FindItem<T>(int pk) where T : Foo
{
return list.OfType<T>().First(it => it.PrimaryKey == 1);
}
用法:
var item = FindItem<FooB>(1);
OfType<T>
对list
有两个有益的影响:
T
和IEnumerable<T>
,因此FindItem
的返回值已经正确输入,无需转换。答案 2 :(得分:0)
在FindItem函数中使用泛型:
public T FindItem<T> (int pk) where T : Foo
{
return list.OfType<T>().SingleOrDefault(it => it.PrimaryKey == pk);
}