Использование LINQ не выходя из вашего кресла:
// Input data:
var first = new[] { "A", "B", "?" };
var second = new[] { "?", "B", "C" };
// This actually filters out pairs where either first or second
// is equal to "?". If you only want to filter out pairs where the
// second is "?", adjust accordingly.
var toCompare = first.Zip(second, Tuple.Create)
.Where(t => t.Item1 != "?" && t.Item2 != "?");
// And now you have a collection of Tuple<string, string>, which
// can be processed in a multitude of ways:
Console.Out.WriteLine(string.Format(
"Compared {0} items, and found {1} of them equal.",
toCompare.Count(),
toCompare.All(t => t.Item1 == t.Item2) ? "all" : "not all"));
Обновление:
Если предикат сравнения (метод, который сравнивает пару элементов и возвращаетлогическое значение) будет более сложным, чем приведенное выше, имеет смысл определить его как лямбду (если он не будет использоваться повторно и достаточно короткий) или как правильный метод в противном случае.
ДляНапример, чтобы реализовать то, что упомянуто в комментарии ниже:
Func<Tuple<string, string>, bool> predicate = t =>
t.Item2 == "?" ||
t.Item2 == "_" && t.Item1 != string.Empty ||
t.Item2 == t.Item1;
// And now you have a collection of Tuple<string, string>, which
// can be processed in a multitude of ways:
Console.Out.WriteLine(string.Format(
"Compared {0} items, and found {1} of them equal.",
toCompare.Count(),
toCompare.All(predicate) ? "all" : "not all"));