Подтвердить что ты не робот

Какая польза от.Скажите. Выберите?

У меня есть тип с неявными операторами преобразования для большинства базовых типов и попытался использовать .Cast<string>() в коллекции этого типа, которая не удалась. Когда я впился в него, я заметил, что кастинг через as не использует неявное или явное преобразование и просто не будет компилироваться, поэтому я предполагаю, что там, где .Cast падает. Таким образом, это не работает

var enumerable = source.Cast<string>();

но это работает

var enumerable = source.Select(x => (string)x);

Итак, какое преимущество Cast? Конечно, это несколько символов короче, но кажется намного более ограниченным. Если его можно использовать для преобразования, есть ли какое-то преимущество, кроме более компактного синтаксиса?

4b9b3361

Ответ 1

Использование роли

Преимущество Cast происходит, когда ваша коллекция реализует только IEnumerable (т.е. не общую версию). В этом случае Cast преобразует все элементы в TResult путем кастинга и возвращает IEnumerable<TResult>. Это удобно, потому что все другие методы расширения LINQ (включая Select) объявляются только для IEnumerable<T>. В коде это выглядит так:

IEnumerable source = // getting IEnumerable from somewhere

// Compile error, because Select is not defined for IEnumerable.
var results = source.Select(x => ((string)x).ToLower());

// This works, because Cast returns IEnumerable<string>
var results = source.Cast<string>().Select(x => x.ToLower());

Cast и OfType - это только два метода расширения LINQ, которые определены для IEnumerable. OfType работает как Cast, но пропускает элементы, которые не относятся к типу TResult, а не выбрасывают исключение.

Влияния и неявные преобразования

Причина, по которой ваш оператор неявного преобразования не работает, когда вы используете Cast, прост: Cast casts object to TResult - и ваше преобразование не определено для object, только для вашего конкретного типа, Реализация для Cast выглядит примерно так:

foreach (object obj in source)
    yield return (TResult) obj;

Этот "отказ" приведения, выполняемый преобразованием, соответствует основным правилам преобразования - как видно из этого примера:

YourType x = new YourType(); // assume YourType defines an implicit conversion to string
object   o = x;

string bar = (string)x;      // Works, the implicit operator is hit.
string foo = (string)o;      // Fails, no implicit conversion between object and string

Ответ 2

Я проверил страницу MSDN для Cast<TResult>, и это метод расширения для типов, которые реализуют (не общий) IEnumerable.

Он может преобразовать класс коллекции (например, ArrayList), который не реализует IEnumerable<T> тем, который делает, позволяя выполнять более богатые операции (такие как Select<T>).