繁体   English   中英

具有泛型类型约束的 C# 多态性

[英]C# Polymorphism with generic type constraints

我正在为IQueryable<Item>创建一个扩展方法,其中Item是实体框架的实体。

扩展方法在第一行返回一个或多个属性值,如果没有找到行或属性值为 null,则返回 null。

这是代码:

internal static TResult FirstOrDefault<TResult>(this IQueryable<Item> items,
        Expression<Func<Item, TResult?>> selector, TResult defaultValue)
        where TResult : struct
{
    var ret = items.Select(selector).FirstOrDefault();

    if (ret == null || !ret.HasValue)
    {
        return defaultValue;
    }

    return ret.Value;
}

internal static TResult FirstOrDefault<TResult>(this IQueryable<Item> items,
        Expression<Func<Item, TResult>> selector, TResult defaultValue)
        where TResult : class
{
    return items.Select(selector).FirstOrDefault() ?? defaultValue;
}

由于属性可能具有值类型值,我决定为值类型和引用类型创建两个扩展方法。

但是当我使用该方法时(见下文),

_dbContext.Items.Where(i => i.Id == '...').FirstOrDefault(i => i.Modified, DateTime.Now)

VS 警告

类型“DateTime”必须是引用类型,以便将其用作泛型类型或方法“EFExtensions.FirstOrDefault(IQueryable, Expresion>, TResult)”中的参数“TResult”

我知道这意味着 VS 尝试使用第二个扩展方法编译此方法,而DateTime将违反where TResult : class约束。

如何在不修改方法名称的情况下让 VS 使用一个?

或者有没有更好的方法来实现我的目标?

任何答案将不胜感激。

谢谢 :)

在您的第一个方法中, Expression的返回类型是一个可为空的TResult因此您需要做的就是返回它。 这可以通过演员表来完成:

_dbContext.Items
    .Where(i => i.Id == '...')
    .FirstOrDefault(i => (DateTime?)i.Modified, DateTime.Now);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM