This seems like it is best done in three steps.
First, you need to figure out what exactly you're supposed to evaluate. This is usually done in two steps called scanning and parsing. The job of scanning is to break the input string into a sequence of tokens, smaller logical units that make up the text. For example, given the string
(a && b)
You would break this into the tokens
(
a
&&
b
)
Typically, this is done using regular expressions, though you can do it by hand as well. The main idea is to separate the task of determining the pieces of the string from the task of seeing how those pieces relate.
Once you've scanned the input, you need to parse it to determine what is being said. That is, you will reassemble the tokens into a complete mathematical expression encoding operator precedence, what operands are being used, etc. There are many algorithms to do this, but perhaps the easiest of them is Dijkstra's shunting yard algorithm, which is fairly easy to implement. You would likely store the output of this parsing step using an abstract syntax tree, a tree structure encoding the structure of the input.
At this point, you have an unambiguous interpretation of the meaning of the expression to evaluate and you'll need to actually evaluate it! To do this, you would probably define, for each AST node, some function to produce a value from that node. For operators like &&, you would evaluate the left and right subexpressions and then compute their AND (or perhaps use short-circuiting to avoid computing the rhs if the lhs is false). For individual letters, you'd use reflection to invoke the corresponding method, or could have a table mapping names to functions (depending on the security you want.)
As a potential optimization in terms of coding, you may want to consider omitting construction of the AST and to just compute the values you want as you go. The shunting-yard algorithm (and many other parsers, such as a top-down LL(1) or bottom-up LR(1) parser) usually let you compute some overall value for an expression in terms of its constituent expressions, and it may be easier to code up this way. However, if you're planning on using the described function over a huge data set like a database, computing the AST would give you an object that you could invoke on each value in the database to produce the values you'd like.
If you are planning on running massively complex queries over a huge set of data, you may even want to go one step further and actually convert the generated expression down to C# code that you would then compile and load into the running program. I've seen examples in Java where this was used to great effect, but this was for a very-high performance application and is probably overkill unless you've exhausted all other options.
Hope this helps!