brgerner
brgerner

Reputation: 4371

in operator in C#

I think there was an in operator in Commodore 128 Basic.
Is there an in operator in c# too?

I mean is there an operator of kind

if(aString in ["a", "b", "c"])  
  Console.Out.WriteLine("aString is 'a', 'b' or 'c'");

Edit1: Currently I need it to decide if an enum value is in a range of some enum values.

Edit2: Thank you all for the Contains() solutions. I will use it in the future. But currently I have a need for enum values. Can I replace the following statement with Contains() or other methods?

public enum MyEnum { A, B, C }

class MyEnumHelper
{
  void IsSpecialSet(MyEnum e)
  {
    return e in [MyEnum.A, MyEnum.C]
  }
}

Edit3: Sorry it was not Basic. I just googled a while and found Turbo Pascal as a candidate where I could saw it. See http://en.wikipedia.org/wiki/Pascal_%28programming_language%29#Set_types

Edit4: Best answers up to now (end of 15 Feb 2012):

Upvotes: 9

Views: 20102

Answers (12)

bvj
bvj

Reputation: 3392

Thanks to my Delphi days, I'm also used to its in keyword. For the generic case in C#, I'm using:

public static class Helper
{
    public static bool In<T>(this T t, params T[] args)
    {
      return args.Contains(t);
    }
  }
}

which can be utilized as follows:

  var color = Color.Aqua;
  var b = color.In(Color.Black, Color.Blue);
  b = "hello".In("hello", "world");

Upvotes: 5

Petr Voborn&#237;k
Petr Voborn&#237;k

Reputation: 1265

Try this:

if ("abc".Contains(aString[0])) 
  Console.WriteLine("aString is 'a', 'b' or 'c'");

Upvotes: 2

JimmiTh
JimmiTh

Reputation: 7449

To answer a follow-up question on Andrew Hare's answer, yes it's possible to restrict the In extension method to a single enum. Don't accept this answer, since Andrew and Trevor answered the revised question (and most answered the original... anyway).

To recap, this is what I find most useful: https://stackoverflow.com/a/5320727/1169696

But if you really want to restrict it, that's just a matter of using the Enum's type as parameter instead of a generic (or Enum):

// This is the one we want to use our In extension method on:
public enum FriendlyEnum
{
    A,
    B,
    C
}

public enum EnemyEnum
{
    A,
    B,
    C
}

// The extension method:
public static class FriendlyEnumExtensions
{
    public static bool In(this FriendlyEnum value, params FriendlyEnum[] list)
    {
        return list.Contains(value);
    }
}

class Program
{
    static void Main(string[] args)
    {
        FriendlyEnum friendlyValue = FriendlyEnum.A;
        EnemyEnum enemyValue       = EnemyEnum.A;

        // Outputs "True":
        Console.WriteLine(friendlyValue.In(FriendlyEnum.A, FriendlyEnum.C));

        // Outputs "False":
        Console.WriteLine(friendlyValue.In(FriendlyEnum.B, FriendlyEnum.C));

        // All of these will result in compiler errors, 
        // because EnemyEnum is invading some way or another:
        Console.WriteLine(friendlyValue.In(EnemyEnum.A, EnemyEnum.B));
        Console.WriteLine(enemyValue.In(FriendlyEnum.A, FriendlyEnum.B));
        Console.WriteLine(enemyValue.In(EnemyEnum.A, EnemyEnum.B));
    }

}

I find it less useful than the generic one I linked - or Trevor's approach - but there you go.

Update

Difference between the approaches:

  • Using Trevor's method, all three mixes of enemy and friend in the code above will be accepted by the compiler (the output will be "True", "False", "False", "False", "True").

  • Using the generic approach, the last one will be accepted (and "True"), because the generics only ensure that all parameters (including this) are of the same type. I.e., it won't accept mixing different enums in the same call.

  • The one above, again, will only accept the one enum you've designed the extension method for.

Upvotes: 1

phoog
phoog

Reputation: 43056

I'm surprised nobody has proposed switch:

class MyEnumHelper 
{ 
    void IsSpecialSet(MyEnum e) 
    { 
        return e in [MyEnum.A, MyEnum.C] 
        switch (e)
        {
            case MyEnum.A:
            case MyEnum.C:
                return true;
            default:
                return false;
        }
    } 
} 

Upvotes: 0

Trevor Pilley
Trevor Pilley

Reputation: 16413

You could use an extension method if you want a slightly more fluent way of working so for this example of a customer and customer status:

public enum CustomerStatus
{
    Active,
    Inactive,
    Deleted
}

public class Customer
{
    public CustomerStatus Status { get; set; }
}

Use the following extension method:

public static class EnumExtensions
{
    public static bool In(this Enum value, params Enum[] values)
    {
        return values.Contains(value);
    }
}

to allow you to write code like this:

private void DoSomething()
{
        var customer = new Customer
        {
            Status = CustomerStatus.Active
        };

        if (customer.Status.In(CustomerStatus.Active, CustomerStatus.Inactive))
        {
            // Do something.
        }
}

Upvotes: 3

James Hill
James Hill

Reputation: 61842

The equivelent in C# would be Contains() (assuming you have a list or array of data)

var myStuff = new List<string> { "a", "b", "c" };
var aString = "a";

if(myStuff.Contains(aString)) {
    //Do Stuff
}

As for the in keyword, it has a different use:

var myStuff = new List<string> { "a", "b", "c" };
var aString = "a";

foreach(string str in myStuff) {
    //Iteration 0 = a, 1 = b, 2 = c
}

Upvotes: 3

Lzh
Lzh

Reputation: 3635

The in keyword is used with foreach only. And no, there isn't such an operator dedicated for such purpose. But you can use built-in methods of the array type or list type as demonstrated below:

        string aString = "a";
        string[] strings = new string[] { "a", "b", "c" };
        if (strings.Contains(aString)) //Contains here is a Linq extension
            Console.WriteLine("aString is either a, b, or c");

        List<string> stringList = new List<string>() { "a", "b", "c" };
        if(stringList.Contains(aString)) //Contains here is a member method
            Console.WriteLine("aString is either a, b, or c");

        if(stringList.IndexOf(aString) != -1)
            Console.WriteLine("aString is either a, b, or c");

Upvotes: 1

John Koerner
John Koerner

Reputation: 38077

Use the contains method:

string[] values = { "A", "B", "C" };

if (values.Contains("A"))           //True
    MessageBox.Show("A is there");

if (values.Contains("b"))               //false, strings are case sensitive
    MessageBox.Show("b is there");  

Upvotes: 1

David
David

Reputation: 73584

Based on your code, you're looking to see if aString is equal to "a", "b", or "c", not whether it contains "a", "b", or "c". If I'm reading the question right, then:

No. Instead, you'd use a switch statement

switch(aString)
{
   case "a:":
   case "b:":
   case "b:":
      Console.Out.WriteLine("aString is 'a', 'b' or 'c'"); 
   default:
      Console.Out.WriteLine("aString is NOT 'a', 'b' or 'c'"); 
}

Upvotes: 1

driis
driis

Reputation: 164331

No. You can come close:

if (new [] { "a", "b", "c" }.Contains(aString))
    Console.Out.WriteLine("aString is 'a', 'b' or 'c'");

Upvotes: 3

Servy
Servy

Reputation: 203843

Most collections will have a .Contains method, and LINQ also has a Contains method, so anything that's enumerable that doesn't already have its own contains method gets one from LINQ.

Upvotes: 1

Andrew Hare
Andrew Hare

Reputation: 351586

Try this:

if(new [] {"a", "b", "c"}.Contains(aString))  
    Console.Out.WriteLine("aString is 'a', 'b' or 'c'");

This uses the Contains method to search the array for aString.

Upvotes: 13

Related Questions