Надеюсь, это не боян, не мог найти что-нибудь связанное онлайнВозвращаясь общий параметр с возвращением выход
я получаю странные ошибки времени компиляции в следующем методе расширения:
public static TCol AddRange<TCol, TItem>(this TCol e, IEnumerable<TItem> values)
where TCol: IEnumerable<TItem>
{
foreach (var cur in e)
{
yield return cur;
}
foreach (var cur in values)
{
yield return cur;
}
}
Ошибка:
The body of 'TestBed.EnumerableExtensions.AddRange(TCol, System.Collections.Generic.IEnumerable)' cannot be an iterator block because 'TCol' is not an iterator interface type
Означает ли это, что общие ограничения, не рассматриваются компилятором при определении, если метод подходит для использования yield return
?
Я использую этот метод расширения в классе, который определяет коллекцию с использованием общего параметра. Нечто подобное (в дополнение к нескольким операторам типа литых):
public class TestEnum<TCol, TItem>
where TCol : class, ICollection<TItem>, new()
{
TCol _values = default(TCol);
public TestEnum(IEnumerable<TItem> values)
{
_values = (TCol)(new TCol()).AddRange(values);
}
public TestEnum(params TItem[] values) : this(values.AsEnumerable()) { }
...
}
И, в свою очередь, используется как (помните, у меня есть операторы приведения типа определены):
TestEnum<List<string>, string> col = new List<string>() { "Hello", "World" };
string someString = col;
Console.WriteLine(someString);
Первоначально мой метод расширения выглядели как :
public static IEnumerable<TItem> AddRange<TItem>(this IEnumerable<TItem> e, IEnumerable<TItem> values)
{
...
}
Что компилирует, но результаты в:
Unhandled Exception: System.InvalidCastException: Unable to cast object of type '<AddRange>d__6
1[System.String]' to type 'System.Collections.Generic.List
1[System.String]'.
Есть ли альтернативный способ сделать это?
В соответствии с просьбой, вот небольшой пример:
class Program
{
public static void Main()
{
TestEnum<List<string>, string> col = new List<string>() { "Hello", "World" };
string someString = col;
Console.WriteLine(someString);
}
}
public class TestEnum<TCol, TItem>
where TCol : class, ICollection<TItem>, new()
{
TCol _values = default(TCol);
public TestEnum(IEnumerable<TItem> values)
{
_values = (TCol)(new TCol()).AddRange(values);
}
public TestEnum(params TItem[] values) : this(values.AsEnumerable()) { }
public static implicit operator TItem(TestEnum<TCol, TItem> item)
{
return item._values.FirstOrDefault();
}
public static implicit operator TestEnum<TCol, TItem>(TCol values)
{
return new TestEnum<TCol, TItem>(values);
}
}
public static class EnumerableExtensions
{
public static IEnumerable<TItem> AddRange<TItem>(this IEnumerable<TItem> e, IEnumerable<TItem> values)
{
foreach (var cur in e)
{
yield return cur;
}
foreach (var cur in values)
{
yield return cur;
}
}
}
Чтобы Репрографический время компиляции исключение:
class Program
{
public static void Main()
{
TestEnum<List<string>, string> col = new List<string>() { "Hello", "World" };
string someString = col;
Console.WriteLine(someString);
}
}
public class TestEnum<TCol, TItem>
where TCol : class, ICollection<TItem>, new()
{
TCol _values = default(TCol);
public TestEnum(IEnumerable<TItem> values)
{
_values = (TCol)(new TCol()).AddRange(values);
}
public TestEnum(params TItem[] values) : this(values.AsEnumerable()) { }
public static implicit operator TItem(TestEnum<TCol, TItem> item)
{
return item._values.FirstOrDefault();
}
public static implicit operator TestEnum<TCol, TItem>(TCol values)
{
return new TestEnum<TCol, TItem>(values);
}
}
public static class EnumerableExtensions
{
public static TCol AddRange<TCol, TItem>(this TCol e, IEnumerable<TItem> values)
where TCol : IEnumerable<TItem>
{
foreach (var cur in e)
{
yield return cur;
}
foreach (var cur in values)
{
yield return cur;
}
}
}
Трудно следить за тем, что происходит со всеми этими фрагментами. Легче было бы ответить на короткий, но * полный * пример. –
Обновлен с примерами. (Обновляется снова, чтобы сделать его короче). –
Вы упомянули ошибку * compile-time *, но ваш пример компилируется. Он не работает с * исключением * во время выполнения - это то, что вы имели в виду, или ваш код просто не показывает то, что вы изначально видели? –