有C#IN运算符吗?


89

在SQL中,可以使用以下语法:

SELECT *
FROM MY_TABLE
WHERE VALUE_1 IN (1, 2, 3)

C#中是否有等效项?IDE似乎将“ in”识别为关键字,但我似乎无法找到任何有关它的信息。

因此,是否可以执行以下操作:

int myValue = 1;
if (myValue in (1, 2, 3))
    // Do something

代替

int myValue = 1;
if (myValue == 1 || myValue == 2 || myValue == 3)
    // Do something

我对此进行了一些编辑以阐明我要比较的内容
Paul Michaels 2010年

检查我添加的另一个答案
Pranay Rana

这已经在stackoverflow上被多次询问了
chiccodoro

3
@chiccodoro如果在此问题之前曾被问过,则将其标记为重复并张贴带有原始问题链接的答案,不要只留下负面评论
Hannish

Answers:


125

如果要编写.In,则可以创建一个扩展名,以便执行此操作。

static class Extensions
{

    public static bool In<T>(this T item, params T[] items)
    {
        if (items == null)
            throw new ArgumentNullException("items");

        return items.Contains(item);
    }

}


class Program
{

    static void Main()
    {


        int myValue = 1;

        if (myValue.In(1, 2, 3))
            // Do Somthing...

        string ds = "Bob";

        if (ds.In("andy", "joel", "matt")) 
        // Do Someting...
    }
}

1
只记得使用System.Linq添加;
Tanner Ornelas

读起来要比包含的要好得多...更容易理解
Konrad

84

List.Contains()我在想你在找什么吗?C#具有in keyword和不具有与operator您在SQL中引用的目的完全不同的目的。

您可以通过两种方法in在C#中使用关键字。假设您在C#中有一个string []或List。

        string[] names; //assume there are some names;

        //find all names that start with "a"
        var results = from str in names
                      where str.StartsWith("a")
                      select str;

        //iterate through all names in results and print
        foreach (string name in results)
        {
            Console.WriteLine(name);
        }

参照您的编辑,我将以这种方式放置您的代码来完成您需要的工作。

        int myValue = 1;
        List<int> checkValues = new List<int> { 1, 2, 3 };

        if (checkValues.Contains(myValue))
            // Do something 

4
人们看到SQL,并立即跳转到LINQ,但这个简单的功能是他想也许正是
巴特面包车Heukelom

29

你可以这样做:

var x = 99; // searched value

if (new[] {1,2,3,99}.Contains(x))
{
   // do something
}

2
我更倾向于选择投票率更高的答案,因为要进行IN而不是重复进行相等性检查的整个目的是为了减少代码复杂度,而且这很好而且又简短又简单!
MrVimes'7

1
谢谢@MrVimes!
JwJosefy

7

您通常使用Contains集合的方法。

myCollection.Where(p => Enumerable.Range(1,3).Contains(p));

希望对您有所帮助。


6

C#中没有“ in”运算符,“ in”关键字仅与“ foreach(... in ...)”或“ from ... in ...”一起使用。

相当于SQL查询的LINQ为:

List<int> list = new List<int> { 1, 2, 3 };
var query = from row in my_table
            where list.Contains(row.value1)
            select row;

4

复制:LINQ to SQL in和not in

select * from table where fieldname in ('val1', 'val2') 

要么

select * from table where fieldname not in (1, 2) 

LINQ to SQL中的IN和NOT IN查询等同于以下内容:

List<string> validValues = new List<string>() { "val1", "val2"}; 
var qry = from item in dataContext.TableName 
          where validValues.Contains(item.FieldName) 
          select item; 

还有这个:

List<int> validValues = new List<int>() { 1, 2}; 
var qry = from item in dataContext.TableName 
          where !validValues.Contains(item.FieldName) 
          select item; 

是的-对不起,我已经编辑了我的问题,因为我要问的内容与linq不相关
Paul Michaels 2010年

4

我同意实现In运算符的最佳方法是使用扩展方法。我做了一些不同的事情:

public static bool In(this string str, string CommaDelimintedStringSet)
{
    string[] Values = CommaDelimintedStringSet.Split(new char[] { ',' });
    foreach (string V in Values)
    {
       if (str == V)
         return true;
    }
    return false;
}

区别在于您不必在每个值前后都加上引号,而只需整个逗号分隔的值集即可,这更容易键入:

bool result = MyString.In("Val1,Val2,Val3");

使用带有此功能的参数数组会更好。喜欢public static bool In(this string str, params string[] stringSet)并称呼它bool result = myString.In("Val1", "Val2", "Val3")
Manuel Hoffmann

2

您可以编写扩展名。我前一次写,是为了使代码像

if(someObject.stringPropertyX.Equals("abc") || someObject.stringPropertyX.Equals("def") || ....){
    //do something
    ...
}else{
   //do something other...
   ....
}

具有扩展性,可读性更高,可以写

if(someObject.stringPropertyX.In("abc", "def",...,"xyz"){
   //do something
   ...
}else{
  //do something other...
  ....
}

这是代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Some.Namespace.Extenders
{
    public static class StringExtender
    {
        /// <summary>
        /// Evaluates whether the String is contained in AT LEAST one of the passed values (i.e. similar to the "in" SQL clause)
        /// </summary>
        /// <param name="thisString"></param>
        /// <param name="values">list of strings used for comparison</param>
        /// <returns><c>true</c> if the string is contained in AT LEAST one of the passed values</returns>
        public static bool In(this String thisString, params string[] values)
        {
            foreach (string val in values)
            {
                if (thisString.Equals(val, StringComparison.InvariantCultureIgnoreCase))
                    return true;
            }

            return false; //no occurence found
        }
    }
}

这是当时针对我的需求的一种,但是您可以对其进行修改和修改以匹配更多不同的类型。


2

对于从0到9的数字:

"123".Contains(myValue)

对于其他任何东西:

"|1|2|3|".Contains("|" + myValue + "|")

2

对于更新的问题,您还可以使用切换语句。

switch (myvalue)
{
   case 1:
   case 2:
   case 3: 
      // your code goes here
  break;
}

1
这就是我最终要做的。我以为共识是C#中实际上没有为此提供任何便利。
保罗·迈克尔斯

5
我真的不会接受这个,因为它不能回答“ in”运算符问题。相反,请参阅投票最多的答案...
chiccodoro

6
我根本不会推荐这种方法!它是不可扩展的,并且有能力使您的程序员同伴的生活陷入困境!
decyclone

3
@decyclone:是的,这与可维护性有关。代码,好像下一个要取代您的程序员是一个串行杀手,并且知道您的住所。
这个。__curious_geek

我不同意,这个问题没有实际答案(或者答案是“不,C#中不存在”)-因此,这似乎是最接近我的选择。您还必须记住,该问题是基于语言功能而不是样式。
保罗·迈克尔斯

1

没有in运算符在集合中寻找值,而是一个称为的方法Contains

最可扩展的解决方案是使用a HashSet作为集合。HashSet与在a List的O(n)运算中进行比较,检查a中的值接近于O(1 )运算。这意味着您可以在中打包很多值,HashSet而且仍然很快速,而在a中查找值List越慢,您拥有的值就越多。

例:

var set = new HashSet<int>();
set.Add(1);
set.Add(2);
set.Add(3);

var result = items.Select(i => set.Contains(i.value));

1

常见的,LINQ方式更强大:

var list = new List<string> { "Tomato", "Orange", "Mango"};
var query = from i in my_table
            from v in list
            where i.Name.StartsWith(v)
            select i;

0

inC#中的关键字用于foreach语句和LINQ查询表达式。inC#本身没有等效于SQL 运算符的功能,但是LINQ提供了类似的功能Contains()

var list = {1, 2, 3}
var filtered = (
    from item in items
    where list.Contains(item)
    select item).ToArray().

0

我做这样的事情:

var shippingAddress = checkoutContext.Addresses.Where(a => (new HashSet<AddressType> { AddressType.SHIPPING_ONLY, AddressType.BILLING_AND_SHIPPING }).Contains(a.AddressType) && a.Id == long.Parse(orderDto.ShippingAddressId)).FirstOrDefault();
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.