Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/305.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 是否有任何重要的理由避免使用'as IQueryable'?_C#_Casting_Iqueryable - Fatal编程技术网

C# 是否有任何重要的理由避免使用'as IQueryable'?

C# 是否有任何重要的理由避免使用'as IQueryable'?,c#,casting,iqueryable,C#,Casting,Iqueryable,我有一个模型到视图的映射扩展方法库。支持它们的是一个基类,它有一些常用方法,包括Transform,如下所示: internal abstract class TransformBase<TOriginal, TConverted> { protected abstract Expression<Func<TOriginal, TConverted>> Expression { get; } public IQueryable<TCon

我有一个模型到视图的映射扩展方法库。支持它们的是一个基类,它有一些常用方法,包括
Transform
,如下所示:

internal abstract class TransformBase<TOriginal, TConverted>
{
    protected abstract Expression<Func<TOriginal, TConverted>> Expression { get; }

    public IQueryable<TConverted> Transform(IEnumerable<TOriginal> value)
    {
        var queryable = value as IQueryable<TOriginal> ?? value.AsQueryable();
        return queryable.Select(Expression);
    }
。。。但是我不想在我的每个依赖类中都编写重载。编辑:为了澄清,下面是一个我想要避免的例子:

public static class TransformCompany
{
    private static readonly TransformBase<Organization, CompanyHeader> header = new TransformPrecompiled<Organization, CompanyHeader>(
    company => new CompanyHeader
    {
        Name = company.Name,
    });

    public static IQueryable<CompanyHeader> AsHeaders(this IQueryable<Organization> companies)
    {
        return header.Transform(companies);
    }

    // Note I have to include this capability in each of my dependent classes
    // Worse is the possibility that someone may accidentally implement
    // only IEnumerable for a future model transformation,
    // causing a hidden data performance problem
    public static IQueryable<CompanyHeader> AsHeaders(this IEnumerable<Organization> companies)
    {
        return header.Transform(companies);
    }
公共静态类转换公司
{
私有静态只读TransformBase标头=新TransformPrecompiled(
公司=>新公司领导
{
Name=公司名称,
});
公共静态IQueryable AsHeaders(本IQueryable公司)
{
返回页眉。转换(公司);
}
//注意:我必须在每个依赖类中包含此功能
//更糟糕的是,有人可能会意外地实施
//对于未来的模型转换,只有IEnumerable,
//导致隐藏的数据性能问题
公共静态可查询的AsHeaders(此IEnumbered companys)
{
返回页眉。转换(公司);
}

如果源类型实现IQueryable, AsQueryable(IEnumerable)直接返回它,否则返回 通过调用等效查询执行查询的IQueryable 运算符方法是可枚举的,而不是可查询的

不要强制转换,而是将
转换
方法简化为

return value.AsQueryable().Select(Expression);

我想说,您不需要对
IEnumerable
IQueryable
进行单独的扩展,因为
IQueryable
继承自
IEnumerable
,而且您也不需要强制转换

查看,
AsQueryable()
实际上为您执行以下检查:

public static IQueryable<TElement> AsQueryable<TElement>(this IEnumerable<TElement> source)
{
    if (source == null)
        throw Error.ArgumentNull("source");
    if (source is IQueryable<TElement>)
        return (IQueryable<TElement>)source;
    return new EnumerableQuery<TElement>(source);
}
公共静态IQueryable AsQueryable(此IEnumerable源代码)
{
if(source==null)
抛出错误。ArgumentNull(“源”);
如果(源是可查询的)
返回(IQueryable)源;
返回新的EnumerableQuery(源);
}
因此,以下内容应适用于您,不会影响性能:

internal abstract class TransformBase<TOriginal, TConverted>
{
    protected abstract Expression<Func<TOriginal, TConverted>> Expression { get; }

    public IQueryable<TConverted> Transform(IEnumerable<TOriginal> value)
    {
        return value.AsQueryable().Select(Expression);
    }
}


public static class TransformCompany
{
    public static IQueryable<CompanyHeader> AsHeaders(this IEnumerable<Organization> companies)
    {
        return header.Transform(companies);
    }
}
内部抽象类转换库
{
受保护的抽象表达式{get;}
公共IQueryable转换(IEnumerable值)
{
返回值.AsQueryable().Select(表达式);
}
}
公共静态类转换公司
{
公共静态可查询的AsHeaders(此IEnumbered companys)
{
返回页眉。转换(公司);
}
}

我不确定你最后一句话的意思。这两套代码在我看来都是一样的,只是第二套更具可读性。我添加了一个例子。请注意,理解澄清并不是回答我的问题的严格必要条件。我的意思并不是说,我只是试图通过我的回答来避免问题脱轨包括这些新信息。@Rhumborl:re:difference,第一个使用反射和强制转换,而第二个不使用。可能还有我忽略的副作用,这就是我提出这个问题的原因。你能进一步澄清你的疑问吗?这是一个性能关键代码吗?我看不到强制转换不好的任何明显原因,扩展也不适合我thod一个人。你在征求建议,但如果没有更广泛的背景,很难给出建议。谢谢。我选择@Rhumborl的答案,因为他也对我的主要问题给出了他的意见,我不需要出于任何原因单独的方法签名。
internal abstract class TransformBase<TOriginal, TConverted>
{
    protected abstract Expression<Func<TOriginal, TConverted>> Expression { get; }

    public IQueryable<TConverted> Transform(IEnumerable<TOriginal> value)
    {
        return value.AsQueryable().Select(Expression);
    }
}


public static class TransformCompany
{
    public static IQueryable<CompanyHeader> AsHeaders(this IEnumerable<Organization> companies)
    {
        return header.Transform(companies);
    }
}