如何从集合 C# 泛型中推断类型

How to infer type from Collection C# Generics

我有来自 System.IO.BinaryReader class 的扩展方法的签名。

public static T ReadCollection<T, R>(this BinaryReader reader, Func<BinaryReader, R> serializeItem) where T : ICollection<R>, new() {...}

然后我这样调用那个方法

IList<User> users = new List<User>();
BinaryReader _reader = new BinaryReader(...);
...
...
 users = _reader.ReadCollection<List<User>, User>(reader => new User
 {
     Id = reader.ReadInt32(),
     Name = reader.ReadString()
 });

我想知道是否可以在不指定用户类型的情况下调用它两次。 ReadCollectionUser>,User>。 无法从用法中推断出类型参数,因此我必须明确声明它,但类型 R 将始终是已定义的 Collection 中的对象。 最后我在泛型类型约束中指定 where T: ICollection<R>

所以最后的调用应该是这样的

_reader.ReadCollection<List<User>>(reader => new User...

而不是

_reader.ReadCollection<List<User>, User>(reader => new User...

提前致谢。

你根本不需要T:

public static ICollection<R> ReadCollection<R>(this BinaryReader reader, Func<BinaryReader, R> serializeItem) {...}

或者您可以将项目添加到 deserializeItem 委托中的任何集合:

public static void ReadCollection(this BinaryReader reader, Action<BinaryReader> deserializeItem) {...}

var users = new List<User>();
_reader.ReadCollection(reader => users.Add(new User {
   Id = reader.ReadInt32(),
   Name = reader.ReadString()
});

如果你放弃 new() 约束(虽然它通常派上用场)并传入一个工厂,它只会调用 'new()' 类型参数可以在调用时被干扰和省略。

public static T ReadCollection<T, R>(this BinaryReader reader, Func<BinaryReader, R> serializeItem, Func<T> listFactory) where T : ICollection<R> {...}

方法体中的 new T() 必须替换为 listFactory()

那你可以这样称呼它

var userList = reader.ReadCollection(reader => new User {..}, () => new List<User>());

var userList = reader.ReadCollection(reader => new User {..}, () => new HashSet<User>());