c#Generics:将List <string>传递给期望List <T>的方法

Gli*_*kot 5 c# generics argument-passing

我第一次涉足仿制药,并对它们有所了解.我有一个方法,旨在接受任何对象的两个列表,匹配它们各种方式并返回匹配/不匹配的对象(方法内的东西可能不是这里的关键).目的是接受任何类型的对象,无论是客户还是其他任何对象.然而,我已经遇到了让它接受'字符串'的问题,我猜是因为它没有使用new()关键字进行初始化,并且不像普通的实例类.

所以,我有一个像这样的方法声明:

public static compareResult<T> stepCompare<T>(List<T> leftList, List<T> rightList, Comparison<T> IDComparer = null, Comparison<T> lowLevelComparer = null, bool confirmUniqueness = true) where T : IComparable, new()
Run Code Online (Sandbox Code Playgroud)

不可否认,在最后添加where子句是为了响应错误"无法创建变量类型'T'的实例,因为它没有new()约束".这出现在方法中的一条线上

T lastItem = new T();
Run Code Online (Sandbox Code Playgroud)

但是,现在,如果我试图将其传递两次Lists<string>,它会说" 'string' must be a non-abstract type with a public parameterless constructor in order to use it as parameter 'T' in the generic type or method 'MF.Comparers.stepCompare<T>(System.Collections.Generic.List<T>, System.Collections.Generic.List<T>, System.Comparison<T>, System.Comparison<T>, bool)'......

任何让这个方法接受的方法都列出了它们是字符串还是其他类?或者将字符串列表放入将被接受的类型的快捷方式?

Jon*_*eet 8

你不能string满足new()约束,不.虽然string 普通类,并且可以使用构造函数以完全正常的方式创建实例,但它没有无参数构造函数.

最好的方法实际上取决于你为什么要有这样的代码行,包括lastItem.如果您只想要一些默认值,那么default(T)可能是最好的方法.

如果你真的想要创建的新实例T,那么你或许应该接受一个Func<T>在方法的参数列表,如按需创建一个默认值的一种方式.或者,如果您对使用特定单个值作为默认值感到满意,则只需添加类型参数即可T.没有看到你的其余代码就很难说.


Mar*_*ell 6

如果你想要任何物体,你可能不需要生活new T().您可以使用反射,特殊情况(string等)的组合来做同样的事情Activator.CreateInstance<T>()- 然而,IMO您应该限制自己(在这种情况下)default(T),对于引用类型(包括字符串)和可空值,它将为null类型,以及非可空值类型的全零.除了满足编译器的明确赋值规则之外,您还应该使用bool或类似的以确保实际上不使用该值.