For fun, I'm going to answer your question directly. Over large data, this will not perform well, but neither will many bit columns.
I think the answer for your overall design to have correct database design, not have a bunch of bit columns, and still perform well is to create a 1 to many table off of your main table, where a record existence means that the option is enabled. This can then be indexed well and perform well. You can also follow a similar construct of lookup table that I'm using below, combined with SUM() across the multiple rows in the child table to convert the multiple records back to your C# enum. Updating the table can also be accomplished with a well crafted MERGE statement. The code for that solution is a little drawn out however and outside the scope of your original question.
CREATE TABLE dbo.Data
(
ID int IDENTITY(1,1) NOT NULL PRIMARY KEY,
Name varchar(50) NOT NULL,
Flags int NOT NULL DEFAULT(0)
);
CREATE TABLE dbo.Flag
(
Value int NOT NULL PRIMARY KEY,
Name varchar(50) NOT NULL
);
INSERT INTO dbo.Flag
SELECT 1, 'Option A'
UNION ALL
SELECT 2, 'Option B'
UNION ALL
SELECT 4, 'Option C';
INSERT INTO dbo.Data (Name, Flags)
SELECT 'George', 0
UNION ALL
SELECT 'Bob', 1
UNION ALL
SELECT 'Bill', 3;
-- for C#
SELECT
d.ID,
d.Name,
d.Flags
FROM
dbo.Data d;
-- for other callers vertical
SELECT
d.ID,
d.Name,
d.Flags,
f.Name AS Flag,
f.Value
FROM
dbo.Data d
LEFT JOIN dbo.Flag f ON
d.Flags & f.Value = f.Value;
-- for other callers horizontal
SELECT
p.Name,
p.[Option A],
p.[Option B],
p.[Option C]
FROM
(
SELECT
d.Name,
f.Name AS Flag,
f.Value
FROM
dbo.Data d
LEFT JOIN dbo.Flag f ON
d.Flags & f.Value = f.Value
) d
PIVOT
(
COUNT(d.Value)
FOR d.Flag IN ([Option A], [Option B], [Option C])
) p;
SELECT
d.ID,
d.Name,
d.Flags
FROM
dbo.Data d
WHERE
EXISTS
(
SELECT *
FROM
dbo.Flag f
WHERE
d.Flags & f.Value = f.Value AND
f.Name IN ('Option A', 'Option B')
);