Небольшое изменение по предложению Яна, без создания новой строки:
var lineNumber = input.Take(pos).Count(c => c == '\n') + 1;
Использование Take
ограничивает размер ввода без необходимости копировать строковые данные.
Вы должны учитывать, каким должен быть результат, если данный символ является переводом строки, кстати ... а также хотите ли вы обрабатывать "foo\rbar\rbaz"
как три строки.
РЕДАКТИРОВАТЬ: Чтобы ответить на новую вторую часть вопроса, вы можете сделать что-то вроде:
var pos = input.Select((value, index) => new { value, index })
.Where(pair => pair.value == '\n')
.Select(pair => pair.index + 1)
.Take(line - 1)
.DefaultIfEmpty(1) // Handle line = 1
.Last();
Я думаю, что это сработает ... но я не уверен, что я бы просто не выписал подход без LINQ ...