T-SQL does not support variadic parameters, and the IN operator is not dynamically variadic, so if you do have this:
SELECT * FROM foo WHERE x IN ( @a, @b, @c, @d )
...and you have more than 4 possible values you'll need to manually add them to your SQL string, like so:
Object[] values = ...
SqlCommand cmd = connection.CreateCommand();
StringBuilder sb = new StringBuilder(" SELECT * FROM foo WHERE x IN (");
for( Int32 i = 0; i < values.Length; i++ ) {
    if( i > 0 ) sb.Append(", ");
    String name = " @param" + i.ToString( CultureInfo.InvariantCulture );
    sb.Append( name );
    cmd.Parameters.Add( name ).Value = values[i];
}
sb.Append( ")" );
cmd.CommandText = sb.ToString();
Obviously this doesn't work for complex queries.
Note that this approach is safe from SQL injection because we never put any values into the SQL string itself.
Another approach is a Table-Valued Parameter, which is much faster and scales to hundreds of thousands of values. SQL Server and SqlClient supports it, but other database systems and client libraries don't.
- Define a table TYPEin your database for the values - even if they're an array of scalar values you still need to define the type.
- See instructions here on how to use Table-Value Parameters with SqlCommand: How to pass table value parameters to stored procedure from .net code
- Perform a - JOINon the table-values:
 - SELECT * FROM foo INNER JOIN @tableParam AS bar ON foo.x = bar.x
 - You can also use the - INoperator with a subquery (that uses the table-parameter), but performance is no better, or worse, compared to a- JOIN:
 - SELECT * FROM foo WHERE x IN ( SELECT x FROM @tableParam )