IEnumerable.Cast <T>выбрасывает InvalidCastException для типа, который поддерживает приведение - PullRequest
0 голосов
/ 27 мая 2020

IEnumerable.Cast должен приводить IEnumerable некоторого типа к типу T.

У меня есть тип, который имеет неявное приведение из строки.

public class MyType
{
    private string _value;

    private MyType(string value)
    {
        _value = value;
    }

    public static implicit operator MyType(string value)
    {
        return new MyType(value);
    }
}

Простой модульный тест показывает, что тип может быть приведен из строки.

[TestMethod]
public void CastSucceeds()
{
    string s = "123";
    var mt = (MyType)s;

    Assert.IsInstanceOfType(mt, typeof(MyType));
}

Просто вызов Cast<T> выполняется без ошибки.

[TestMethod]
public void IEnumerableCastSeemsToSucceed()
{
    IEnumerable<string> strings = new List<string> { "Foo", "Bar" };
    var myTypes = strings.Cast<MyType>();

    Assert.IsInstanceOfType(myTypes, typeof(IEnumerable<MyType>));
}

Но когда я действительно перечисляю, я получаю InvalidCastException.

[TestMethod]
public void IEnumerableCastToListFails()
{
    IEnumerable<string> strings = new List<string> { "Foo", "Bar" };
    var myTypes = strings.Cast<MyType>();

    var list = myTypes.ToList();

    Assert.IsInstanceOfType(list, typeof(List<MyType>));
}
Test failed: IEnumerableCastToListFails Duration: 13,00ms
Failure:
System.InvalidCastException : Unable to cast object of type 'System.String' to type 'MyType'.
Stack Trace:
   at System.Linq.Enumerable.d__97`1.MoveNext()
   at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
   at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
   at IEnumerableCastToListFails()

Я не понимаю, почему я получаю это исключение. Мой первый тест доказывает, что мы можем преобразовать System.String в Mytype. Я неправильно понял возможности IEnumerable.Cast? Как я могу решить эту проблему?

Обновление: мой вопрос отмечен как повторяющийся, но упомянутые вопросы касаются преобразования из int в long. Ответы говорят о боксе и распаковке. Я думаю, что в моей ситуации это не так. И string, и MyType являются ссылочными типами, поэтому упаковки не должно происходить. Думаю, поможет, если кто-нибудь ответит, почему Cast<T> не работает для пользовательских типов, в которых реализован оператор приведения.

...