我第一次涉足仿制药,并对它们有所了解。我有一个方法,旨在接受任何对象的两个列表,匹配它们各种方式并返回匹配/不匹配的对象(方法内的东西可能不是这里的关键)。目的是接受任何类型的对象,无论是客户还是其他任何对象。然而,我已经遇到了让它接受'字符串'的问题,我猜是因为它没有使用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()
不可否认,最后添加where子句是为了响应错误“无法创建变量类型'T'的实例,因为它没有new()约束”。这出现在方法中的一行
T lastItem = new T();
但是,现在如果我尝试将其传递给两个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)'
...
任何让这个方法接受的方法都列出了它们是字符串还是其他类?或者将字符串列表放入将被接受的类型的快捷方式?
答案 0 :(得分:8)
你不能让string
满足new()
约束,不。虽然string
是正常类,并且可以使用构造函数以完全正常的方式创建实例,但它没有无参数构造函数。
最好的方法实际上取决于为什么你有这行代码,包括lastItem
。如果您只想要一些默认值,那么default(T)
可能是最好的方法。
如果您真的做想要创建T
的新实例,那么您应该在方法的参数列表中接受Func<T>
,作为创建按需默认值。或者,如果您对使用特定单个值作为默认值感到满意,则只需添加T
类型的参数即可。没有看到你的其余代码就很难说。
答案 1 :(得分:6)
如果您想要任何对象,您可能必须没有new T()
。你可以 使用反射,特殊情况(string
等)和Activator.CreateInstance<T>()
的组合来做同样的事情 - 但是,IMO你应该限制自己(在这种情况下)到default(T)
,对于引用类型(包括字符串)和可空值类型将为null,对于不可为空的值类型将为全零。除了满足编译器的明确赋值规则外,您还应该使用bool
或类似内容来确保实际上 使用该值。