Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.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# 如果我将IQueryable强制转换为IEnumerable,然后调用Linq扩展方法,将调用哪个实现?_C#_Linq_Extension Methods - Fatal编程技术网

C# 如果我将IQueryable强制转换为IEnumerable,然后调用Linq扩展方法,将调用哪个实现?

C# 如果我将IQueryable强制转换为IEnumerable,然后调用Linq扩展方法,将调用哪个实现?,c#,linq,extension-methods,C#,Linq,Extension Methods,考虑到以下准则: IQueryable<T> queryable; // something to instantiate queryable var enumerable = (IEnumerable<T>) queryable; var filtered = enumerable.Where(i => i > 3); 输出是“MyString方法”。当您运行这个简单的程序时,它解释了重载是如何工作的:)。答案是将调用底层类型的方法。对于IQuery

考虑到以下准则:

IQueryable<T> queryable;

// something to instantiate queryable

var enumerable = (IEnumerable<T>) queryable;

var filtered = enumerable.Where(i => i > 3);

输出是“MyString方法”。

当您运行这个简单的程序时,它解释了重载是如何工作的:)。答案是将调用底层类型的方法。对于
IQueryable
IEnumerable
,它应该以相同的方式工作;也就是说,将调用原始对象的方法,因为即使我们将其转换为其他类型,实际实现也是原始类型的。但是,当存在扩展方法时,将使用引用对象的扩展方法,因此在这种情况下,它取决于扩展方法中的逻辑。扩展方法可以通过巧妙的logit来查看对象是否为实际类型,然后在执行该方法之前将其强制转换回

class Program
{
    static void Main(string[] args)
    {
        MyString2 myString2 = new MyString2();
        var myString = (MyString)myString2;
        Console.WriteLine(myString); // prints "ToString of MyString2"
        Console.WriteLine(myString.GiveMeTheString()); // prints "GiveMeTheString of MyString2"
        Console.ReadLine();
    }
}

public class MyString
{
    public string MyProperty { get; set; }
    public override string ToString()
    {
        return "ToString of MyString";
    }
}
public class MyString2 : MyString
{
    public string MyProperty { get; set; }
    public override string ToString()
    {
        return "ToString of MyString2";
    }
}

public static class Extensions
{
    public static string GiveMeTheString(this MyString myString)
    {
        return "GiveMeTheString of MyString";
    }
    public static string GiveMeTheString(this MyString2 myString)
    {
        return "GiveMeTheString of MyString2";
    }
}

目前公认的答案是虚拟方法,而不是扩展方法


如果将IQueryable强制转换为IEnumerable,然后调用其中一个扩展方法(例如,问题中的Where(…),那么将调用可枚举版本上的扩展方法,而不是可查询的扩展方法。

谢谢Tomas!我知道我应该能够通过编码解决这个问题,但我的大脑不工作了!至少现在,虽然其他搜索解决方案的人可能会看到这篇文章。我应该补充一点-答案是将调用更具体(IQueryable)的扩展方法。这发生在我们当中最好的人身上。记住投票并接受答案,这样其他人可以更容易地找到答案;也就是说,如果它是正确的话。我会在我的答案中添加这一部分。你的例子是虚拟方法,问题涉及扩展方法,因此你的答案不适用。铱星是正确的,对不起,托马斯!我用证据更新了我原来的帖子。我也会将Iridium的答案标记为正确,但是Tomas仍然得到+1来帮助启动代码!忘了投票赞成这个问题。。。发现这一点很有趣:)。记住,扩展方法语法只是调用静态方法的一种语法糖,静态方法根据定义使用静态分析来确定要调用的方法。如果需要运行时分析,则需要自己编写代码来完成。此外:静态地作为IE的IQ不希望意外地变形回IQ代码路径;大概你把它投给IE是因为你不想把它当作智商!如果你想把它当作智商,那就不要把它丢掉。格劳乔法则:如果你那样做会受伤,不要那样做。
class Program
{
    static void Main(string[] args)
    {
        MyString2 myString2 = new MyString2();
        var myString = (MyString)myString2;
        Console.WriteLine(myString); // prints "ToString of MyString2"
        Console.WriteLine(myString.GiveMeTheString()); // prints "GiveMeTheString of MyString2"
        Console.ReadLine();
    }
}

public class MyString
{
    public string MyProperty { get; set; }
    public override string ToString()
    {
        return "ToString of MyString";
    }
}
public class MyString2 : MyString
{
    public string MyProperty { get; set; }
    public override string ToString()
    {
        return "ToString of MyString2";
    }
}

public static class Extensions
{
    public static string GiveMeTheString(this MyString myString)
    {
        return "GiveMeTheString of MyString";
    }
    public static string GiveMeTheString(this MyString2 myString)
    {
        return "GiveMeTheString of MyString2";
    }
}