【问题标题】:How to overload a method to accept a Linq expression如何重载方法以接受 Linq 表达式
【发布时间】:2012-03-22 15:34:10
【问题描述】:

设置

我有一个名为 WhereIn() 的方法,它接受一个参数 object[] 值:

public bool WhereIn(params object[] values)

问题

不幸的是,拨打WhereIn(values.Select(v => v.Id)) 真的很容易出错。

这会导致传入 Linq 表达式,而不是将值枚举到数组中。如何重载我的方法以接受 linq 表达式?

我的最佳猜测

我目前最好的猜测是做一个 IEnumerable 重载,然后必须检查它是否是一个字符串,然后将该字符串填充到一个对象数组中以调用另一个重载:

public bool WhereIn<T>(IEnumerable<T> values){
    if(values.GetType().Name == "String"){
        return WhereIn(new object[]{values});
    } else {
        // Do Stuff
    }
}

我对必须手动检查字符串类型并不满意,而且我担心我可能会错过其他一些实现 IEnumerable 的类,它应该被包装在一个对象数组中。

【问题讨论】:

  • WhereIn的语义是什么?
  • @Jon 它创建了一个 Microsoft CRM QueryExpression,用于在服务器端生成 SQL 语句。所以我这样使用它: crmdataContext.GetAllEntitiesWhereIn("contactid", guid1, guid2, guid3);

标签: c# linq linq-to-entities


【解决方案1】:

如果你有以下两个签名:

public bool WhereIn<T>(params T[] values);
public bool WhereIn<T>(IEnumerable<T> values);

...你这样称呼它:

WhereIn("hi")

这将调用第一个方法,传递给它一个单元素string[]

【讨论】:

  • 这实际上可能有效。我只是想有一种方法可以指定一个接受 linq 表达式的方法,例如 list.select(i => i.Id);
  • @Daryl: list.select(i =&gt; i.Id) 返回一个IEnumerable&lt;T&gt;,所以这会起作用。
  • @Daryl 您是说您希望您的方法采用IEnumerable&lt;T&gt; 和 linq 表达式吗?
  • @Craig 基本上,如果您尝试传入 list.select(i => i.id),它会编译得很好,但运行时会爆炸。所以我需要将结果枚举到一个数组(调用 ToArray),然后调用 params object[] 重载。如果 params 数组的长度为 1,我可以做一些奇怪的类型检查,但是开发人员不知道我在做什么以及为什么 list.select(i => i.ID) 会神奇地起作用。
  • @Daryl:为什么它会“在运行时轰炸”?我已经对此进行了测试,如果您传入list.Select(i =&gt; i.Id),它就可以正常工作。
【解决方案2】:

您可能想查看System.Collections.Generic.Contains() 方法,并免去尝试“重新发明轮子”的不必要的头痛。

【讨论】:

  • 除了我实际上将这些参数传递给我不拥有的另一个方法,它是 Microsoft CRM 的一部分,然后用于构建 QueryExpression 并查询数据库。不包含任何工作。 :)
  • 一个你想要实现的现实例子会很有帮助。
【解决方案3】:

如果你做了这样的事情…… 编辑:我包含了一个测试方法,因此您可以根据需要尝试不同的 select(a => a.Id)

[TestMethod]
public void Test()
{
    var test = new[] {
        new { Id = 1, Name = "John" },
        new { Id = 2, Name = "George" },
    };

    if (WhereIn(test.Select(a => a.Name)))
    {

    }


}

//Works with value types, strings, and classes
public bool WhereIn<T>(IEnumerable<T> values)
{
    var objectArray = new object[values.Count()];

    for (int index = 0; index < values.Count(); index++)
    {
        objectArray[index] = values.ElementAt(index);
    }

    return WhereIn(objectArray);
}

// This was just for test purposes
public bool WhereIn(params object[] values)
{

     return true;
}

我已经在 Visual Studio 测试中运行了它,并且似乎可以工作。

希望这会有所帮助。

【讨论】:

  • 除非字符串对象会惨遭失败并且值类型数组不是协变的。
  • 我明白了...我已经进行了调整。为我工作。
【解决方案4】:

我没试过,但你不能做吗

WhereIn(values.Select(v => v.Id).ToArray<Type_of_Value>())

其中 Type_of_Value 是您的值集合中使用的类型

【讨论】:

  • idk,我没有对你投反对票。 ToArray 理想情况下是我需要调用的,唯一的问题是如果你忘记了不会出现编译器错误,但它会导致程序出错。所以我正在努力创造更多的成功之坑 (blogs.msdn.com/b/brada/archive/2003/10/02/50420.aspx)
猜你喜欢
  • 1970-01-01
  • 2021-08-14
  • 2014-09-07
  • 2021-09-29
  • 1970-01-01
  • 1970-01-01
  • 2011-02-14
  • 2020-01-28
  • 1970-01-01
相关资源
最近更新 更多