我正在尝试创建一种通用方法来保存应针对给定类搜索的属性。
我创建了以下结构来保存此信息:
public struct Lookup<T> where T: BaseEntity
{
public Expression<Func<T, object>> Parent { get; set; }
}
然后创建了一个字典,如下所示:
readonly Dictionary<string, Lookup<BaseEntity>> _dict =
new Dictionary<string, Lookup<BaseEntity>>();
我有一个使用BaseEntity
作为基础类的类:
public class Agency : BaseEntity
{
public int AgencyId { get; set; }
}
我使用以下信息创建一个新的Lookup结构:
new Lookup<Agency>
{
Parent = x => x.Id
};
但是,如果我尝试将其添加到字典中,则会出现以下错误:
Cannot convert from Lookup<Agency> to Lookup<BaseEntity>
我本来以为这是可行的,因为它们是相同的基本类型,这是怎么回事。
我有很多实体要添加,因此希望能通用地实现它,而不必执行if / switch等。
谢谢
不,Lookup<BaseEntity>
不是的基本类型Lookup<Agency>
。Agency
仅从BaseEntity
中得出的事实还不够。但是首先,让我们看看其他的东西。
考虑一下通常的方差规则。您的方法对应于
object DoSomething(T x) { ... }
现在,在中Lookup<BaseEntity>
,
object DoSomething(BaseEntity x) { ... }
到目前为止,一切都很好-Agency
代替,是完全合法的BaseEntity
,因为Agency
源自BaseEntity
。然而,这不是这种情况,你有。您创建了这个:
object DoSomething(Agency x) { ... }
显然,您不能通过BaseEntity
而不是Agency
-这样会完全打断您的输入。而且与Java不同,C#(和.NET通常)的泛型在编译时和运行时都是真实的,它们不会退一步Lookup<BaseEntity>
。
此外,C#/。NET限制了方差的使用。您可以在简单的表达式和委托中免费获得方差,但不能在类或泛型类中获得方差。您需要明确说明所需的差异类型,并使用接口。例如,在您的情况下,您将具有以下内容:
public interface ILookup<out T>
这将允许您执行从ILookup<Agency>
到的转换ILookup<BaseEntity>
。但是,这对于您的情况T
是不够的,因为在您的情况下既是协变的又是协变的-换句话说,您不能朝任一方向进行转换。
但是,这没什么大不了的,因为您使事情变得有些复杂。虽然您需要强大的类型来创建Lookup<Agency>
,但您并不需要类型本身-Expression
无论如何,您都将使用untyped :
public sealed class Lookup
{
private readonly Expression parent;
private Lookup(Expression parent)
{
this.parent = parent;
}
public Expression Parent { get { return parent; } }
public static Lookup For<T>(Expression<Func<T, object>> member)
where T : BaseEntity
{
return new Lookup(member);
}
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句