简体   繁体   中英

C# syntactic sugar similar to SQL's IN comparison?

I often find myself writing conditionals similar to the following:

if(Path.GetExtension(filename) == ".pdf" || Path.GetExtension(filename)== ".doc")
{
    // do something
}

Calling Path.GetExtension() once per each file extension I want to test seems a little redundant. Granted, I could do something like this:

string fileExtension = Path.GetExtension(filename);
if(fileExtension == ".pdf" || fileExtension == ".doc")
{
    // do something
}

but considering I'm only using the fileExtension for the comparison and nothing else, declaring a variable for the file extension doesn't seem very elegant.

In SQL, I could use the IN operator:

SELECT file FROM table WHERE fileExtension IN(".pdf", ".doc")

which allows me to perform the test without no repetition.

Does C# offer any syntactic sugar similar to SQL's in, where I don't have to repeat the variable being compared or the equality operator?

Just create a new array inline and call Contains :

if((new[]{ ".pdf", ".doc"}).Contains(fileExtension))
{
    // Do Something
}

If you care about readability you could go for a

switch (fileExtension)
{
    case ".pdf":
    case ".doc":
        // do something                
        break;
}

It is also future proof in case you have to handle other extentions differently.

Justin's answer would certainly do it. But seems like overkill to me. Certainly, unless you already have the extensions you are comparing against in a collection, it seems that would be quite a bit less efficient than simply comparing them directly like you do in your second example. (Your first example is a bad approach IMO.)

But note that storing the result in a variable as you do in your second example could be extremely efficient. If the variable is only used in the comparison that follows, there are all sorts of optimizations the compiler could make. It might not even have to create a variable at all.

While I see that you've accepted a solution already, I'd like to submit mine as I think it follows your intent much more closely.

public static bool In(this object source, params object[] collection)
{
    return collection.Contains(source);
}

Usage:

if(Path.GetExtension(filename).In(".pdf", ".doc"))
{
    //Do something
}

Hope that helps.

EDIT: Added periods to the file extensions to accurately reflect how "GetExtension" functions.

If you really want it to read like the SQL operator, you could use an extension method.

public static bool In(this object o, IEnumerable c)
{
    foreach (object i in c)
    {
        if (i.Equals(o))
        {
            return true;
        }
    }
    return false;
}

Usage:

string fileExtension = ".pdf";
string[] acceptedFileExtensions = new[] { ".pdf", ".doc" };

if (fileExtension.In(acceptedFileExtensions))
{
    // Do something
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM