我想弄清楚如何在C#中使用模板.我写了这个:
public static List<TValue> deepcopyList<TValue>(List<TValue> src) { List<TValue> arr = new List<TValue>(); for (int i = 0; i < src.Count; i++) { arr.Add(new TValue(src[i])); //Error on this line } return arr; }
error CS0304: Cannot create an instance of the variable type ‘TValue’
because it does not have the new() constraint
解决方法
#1:接口的新约束
向TValue添加一个约束,告诉编译器它有一个无参数构造函数.您可以通过在TValue的约束中添加关键字new来实现此目的.这样你至少可以构建一个项目.
您不能使用通用参数类型的参数.但您可以使用另一个约束来定义一些属性:
public interface IMyValue<TValue> { void copyFrom(TValue original); } public static List<TValue> deepcopyList<TValue>(List<TValue> src) where TValue: IMyValue<TValue>,new() // <== Setting the constraints of TValue. { List<TValue> arr = new List<TValue>(); for (int i = 0; i < src.Count; i++) { TValue value = new TValue(); value.copyFrom(src[i]); arr.Add(value); // No error. } return arr; }
#2:使用ICloneable
还有第二种解决方案,它有点相同.使用ICloneable
使值自行关闭它:
public static List<TValue> deepcopyList<TValue>(List<TValue> src) where TValue: ICloneable // <== Setting the constraints of TValue. { List<TValue> arr = new List<TValue>(); for (int i = 0; i < src.Count; i++) { TValue value = (TValue)src[i].Clone(); arr.Add(value); // No error. } return arr; }
#3:使用Activator
但是,既然你想创建一个深度克隆,那么还有另一种方法,就是使用Activator.此方法不是类型安全的,并且当类型不支持该构造函数调用时可以生成运行时异常:
public static List<TValue> deepcopyList<TValue>(List<TValue> src) { List<TValue> arr = new List<TValue>(); for (int i = 0; i < src.Count; i++) { TValue value = (TValue)Activator.CreateInstance(typeof(TValue),src[i]); arr.Add(value); // Possible runtime rror. } return arr; }
上面的方法也可以通过使用反射替换并获取正确的ConstructorInfo并使用它来创建新项目.这与Activator的作用相同,并且具有相同的风险.
顺便说一句:在C#中,它被称为’通用’,而不是像C中那样的’模板’.
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。