如何在C#中编写这样的类?
我在一个项目中有多个完全相同的类,除了类的名称。基本上,它们表示运行时从配置文件加载的美化枚举。这些类如下所示:如何在C#中编写这样的类?,c#,.net,code-generation,code-duplication,C#,.net,Code Generation,Code Duplication,我在一个项目中有多个完全相同的类,除了类的名称。基本上,它们表示运行时从配置文件加载的美化枚举。这些类如下所示: public class ClassName : IEquatable<ClassName> { public ClassName(string description) { Description = description; } public override bool Equals(object obj) {
public class ClassName : IEquatable<ClassName> {
public ClassName(string description) {
Description = description;
}
public override bool Equals(object obj) {
return obj != null &&
typeof(ClassName).IsAssignableFrom(obj.GetType()) &&
Equals((ClassName)obj);
}
public bool Equals(ClassName other) {
return other != null &&
Description.Equals(other.Description);
}
public override int GetHashCode() {
return Description.GetHashCode();
}
public override string ToString() {
return Description;
}
public string Description { get; private set; }
}
public class ClassName1 : MyBase<ClassName1> { ... }
public class ClassName2 : MyBase<ClassName2> { ... }
public class ClassName3 : MyBase<ClassName3> { ... }
公共类类名:IEquatable{
公共类名(字符串描述){
描述=描述;
}
公共覆盖布尔等于(对象对象对象){
返回对象!=null&&
typeof(ClassName).IsAssignableFrom(obj.GetType())&&
等于((类名)obj);
}
公共布尔等于(类名称其他){
返回其他!=null&&
Description.Equals(其他.Description);
}
公共覆盖int GetHashCode(){
返回Description.GetHashCode();
}
公共重写字符串ToString(){
返回说明;
}
公共字符串说明{get;private set;}
}
我认为没有理由复制这个文件并多次更改类名。当然,有一种方法我可以列出我想要的类,并让它们自动为我创建。如何?您考虑过了吗?您考虑过了吗?我建议您自己创建代码片段,这将是快速而简单的。我建议您自己创建代码片段,这将是快速而简单的。我建议使用T4。与代码片段相比,这种方法的一个重要优点是,如果更改模板,则所有代码都将更新以匹配 将其放入扩展名为
.tt
<#@ template language="C#" #>
<#@ output extension=".codegen.cs" #>
<#@ assembly name="System.dll" #>
<#@ import namespace="System" #>
// <auto-generated>
// This code was generated by a tool. Any changes made manually will be lost
// the next time this code is regenerated.
// </auto-generated>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace MyStuff
{
<# foreach (string classname in classes) {#>
public class <#= classname #> : IEquatable<ClassName>
{
public <#= classname #>(string description) {
Description = description;
}
public override bool Equals(object obj) {
return obj != null &&
typeof(<#= classname #>).IsAssignableFrom(obj.GetType()) &&
Equals((<#= classname #>)obj);
}
public bool Equals(<#= classname #>other) {
return other != null &&
Description.Equals(other.Description);
}
public override int GetHashCode() {
return Description.GetHashCode();
}
public override string ToString() {
return Description;
}
public string Description { get; private set; }
}
}
<# } #>
}
<#+ string[] classes = new string[] { "Class1",
"Class2" };
#>
//
//这段代码是由一个工具生成的。手动所做的任何更改都将丢失
//下次重新生成此代码时。
//
使用制度;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
名称空间MyStuff
{
公共类:IEquatable
{
公共(字符串描述){
描述=描述;
}
公共覆盖布尔等于(对象对象对象){
返回对象!=null&&
typeof().IsAssignableFrom(obj.GetType())&&
等于(()obj);
}
公共布尔等于(其他){
返回其他!=null&&
Description.Equals(其他.Description);
}
公共覆盖int GetHashCode(){
返回Description.GetHashCode();
}
公共重写字符串ToString(){
返回说明;
}
公共字符串说明{get;private set;}
}
}
}
VS将为您生成一个源文件。需要新类时,只需添加到数组
类即可。我建议使用T4。与代码片段相比,这种方法的一个重要优点是,如果更改模板,则所有代码都将更新以匹配
将其放入扩展名为.tt
<#@ template language="C#" #>
<#@ output extension=".codegen.cs" #>
<#@ assembly name="System.dll" #>
<#@ import namespace="System" #>
// <auto-generated>
// This code was generated by a tool. Any changes made manually will be lost
// the next time this code is regenerated.
// </auto-generated>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace MyStuff
{
<# foreach (string classname in classes) {#>
public class <#= classname #> : IEquatable<ClassName>
{
public <#= classname #>(string description) {
Description = description;
}
public override bool Equals(object obj) {
return obj != null &&
typeof(<#= classname #>).IsAssignableFrom(obj.GetType()) &&
Equals((<#= classname #>)obj);
}
public bool Equals(<#= classname #>other) {
return other != null &&
Description.Equals(other.Description);
}
public override int GetHashCode() {
return Description.GetHashCode();
}
public override string ToString() {
return Description;
}
public string Description { get; private set; }
}
}
<# } #>
}
<#+ string[] classes = new string[] { "Class1",
"Class2" };
#>
//
//这段代码是由一个工具生成的。手动所做的任何更改都将丢失
//下次重新生成此代码时。
//
使用制度;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
名称空间MyStuff
{
公共类:IEquatable
{
公共(字符串描述){
描述=描述;
}
公共覆盖布尔等于(对象对象对象){
返回对象!=null&&
typeof().IsAssignableFrom(obj.GetType())&&
等于(()obj);
}
公共布尔等于(其他){
返回其他!=null&&
Description.Equals(其他.Description);
}
公共覆盖int GetHashCode(){
返回Description.GetHashCode();
}
公共重写字符串ToString(){
返回说明;
}
公共字符串说明{get;private set;}
}
}
}
VS将为您生成一个源文件。当您需要一个新类时,只需将类添加到数组中。如果这些类确实完全相同,您是否可以使用继承?代码量非常小,不需要任何额外的前/后处理
public class Equatable : IEquatable { ... }
public class ClassName1 : Equatable {}
public class ClassName2 : Equatable {}
public class ClassName3 : Equatable {}
public class ClassName4 : Equatable {}
注意:如果您需要更改某些内容,所有代码片段建议似乎都会成为维护过程中的噩梦。如果类确实完全相同,您是否可以使用继承?代码量非常小,不需要任何额外的前/后处理
public class Equatable : IEquatable { ... }
public class ClassName1 : Equatable {}
public class ClassName2 : Equatable {}
public class ClassName3 : Equatable {}
public class ClassName4 : Equatable {}
注意:如果您需要更改某些内容,所有代码段建议似乎都会成为维护过程中的噩梦。您能将继承与泛型结合使用吗
public class MyBase<T> : IEquatable<MyBase<T>>
where T : MyBase
{
public ClassName(string description) {
Description = description;
}
public override bool Equals(object obj) { ... }
public bool Equals(T other) {
return other != null &&
Description.Equals(other.Description);
}
public override int GetHashCode() { ... }
public override string ToString() { ... }
public string Description { get; private set; }
}
公共类MyBase:IEquatable
其中T:MyBase
{
公共类名(字符串描述){
描述=描述;
}
公共覆盖布尔等于(对象对象对象){…}
公共布尔等于(T其他){
返回其他!=null&&
Description.Equals(其他.Description);
}
公共重写int GetHashCode(){…}
公共重写字符串ToString(){…}
公共字符串说明{get;private set;}
}
然后你可以像这样继承:
public class ClassName : IEquatable<ClassName> {
public ClassName(string description) {
Description = description;
}
public override bool Equals(object obj) {
return obj != null &&
typeof(ClassName).IsAssignableFrom(obj.GetType()) &&
Equals((ClassName)obj);
}
public bool Equals(ClassName other) {
return other != null &&
Description.Equals(other.Description);
}
public override int GetHashCode() {
return Description.GetHashCode();
}
public override string ToString() {
return Description;
}
public string Description { get; private set; }
}
public class ClassName1 : MyBase<ClassName1> { ... }
public class ClassName2 : MyBase<ClassName2> { ... }
public class ClassName3 : MyBase<ClassName3> { ... }
public类ClassName1:MyBase{…}
公共类ClassName2:MyBase{…}
公共类ClassName3:MyBase{…}
您可以将继承与泛型一起使用吗
public class MyBase<T> : IEquatable<MyBase<T>>
where T : MyBase
{
public ClassName(string description) {
Description = description;
}
public override bool Equals(object obj) { ... }
public bool Equals(T other) {
return other != null &&
Description.Equals(other.Description);
}
public override int GetHashCode() { ... }
public override string ToString() { ... }
public string Description { get; private set; }
}
公共类MyBase:IEquatable
其中T:MyBase
{
公共类名(字符串描述){
描述=描述;
}
公共覆盖布尔等于(对象对象对象){…}
公共布尔等于(T其他){
返回其他!=null&&
Description.Equals(其他.Description);
}
公共重写int GetHashCode(){…}
公共重写字符串ToString(){…}
公共字符串说明{get;private set;}
}
然后你可以像这样继承:
public class ClassName : IEquatable<ClassName> {
public ClassName(string description) {
Description = description;
}
public override bool Equals(object obj) {
return obj != null &&
typeof(ClassName).IsAssignableFrom(obj.GetType()) &&
Equals((ClassName)obj);
}
public bool Equals(ClassName other) {
return other != null &&
Description.Equals(other.Description);
}
public override int GetHashCode() {
return Description.GetHashCode();
}
public override string ToString() {
return Description;
}
public string Description { get; private set; }
}
public class ClassName1 : MyBase<ClassName1> { ... }
public class ClassName2 : MyBase<ClassName2> { ... }
public class ClassName3 : MyBase<ClassName3> { ... }
public类ClassName1:MyBase{…}
公共类ClassName2:MyBase{…}
公共类ClassName3:MyBase{…}
为什么普通的类继承不起作用?那么你唯一要重复的就是c