-
Notifications
You must be signed in to change notification settings - Fork 12
Description
The current signature of Bencodex.Types.List(IEnumerable<IValue>) constructor requires frequent type casting to IEnumerable<IValue>, because C# does not automatically infer G<T> where T : B to G<B>. For example, the following code fails to build:
int[] ints = { 1, 2, 3, 4 };
IEnumerable<Bencodex.Types.Integer> bInts =
ints.Select(i => (Bencodex.Types.Integer)i);
var list = new Bencodex.Types.List(bInts); // Type errorIt's because IEnumerable<Bencodex.Types.Integer> cannot be passed to IEnumerable<IValue>, even though Bencodex.Types.Integer implements IValue. Instead, we need to explicitly cast bInts so that the code is compiled:
var list = new Bencodex.Types.List(bInts.Cast<IValue>());This can be fixed by changing the parameter type from IEnumerable<IValue> instead of IEnumerable<T> where T : IValue. However, unfortunately .NET disallows constructors to have type parameters. Therefore, we need add a separate factory method instead:
public static List From<T>(IEnumerable<T> values)
where T : IValue;Or, we might be better to have extension methods on IEnumerable<T> where T : IValue instead:
public static class EnumerableExtensions
{
public static Bencodex.Types.List ToBencodexList<T>(this IEnumerable<T> source)
where T : IValue;
public static Bencodex.Types.Dictionary ToBencodexDictionary<TKey, TValue>(
this IEnumerable<KeyValuePair<TKey, TValue>> source
)
where TKey : IKEy
where TValue : IValue;
}