I have multiple classes in a project that are exactly the same except for the name of the class. Basically, they represent glorified enums loaded at runtime from config files. The classes look like this:
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(o开发者_如何学运维ther.Description);
}
public override int GetHashCode() {
return Description.GetHashCode();
}
public override string ToString() {
return Description;
}
public string Description { get; private set; }
}
I see no reason to copy this file and change the class name multiple times. Surely there's a way I can just list what classes I want and have them automatically created for me. How?
I'd suggest using T4. A substantial advantage of this over code snippets is that if you change your template then all of your code will be updated to match.
Put this in a file with the extension .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" };
#>
VS will generate a source file for you. Just add to the array classes
when you need a new class.
Could you use inheritance with generics?
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; }
}
Then you could inherit like this:
public class ClassName1 : MyBase<ClassName1> { ... }
public class ClassName2 : MyBase<ClassName2> { ... }
public class ClassName3 : MyBase<ClassName3> { ... }
Have you considered code snippets?
If the classes really are the exact same, could you just use inheritance? The amount of code is pretty small and it doesn't require any extra pre/post processing.
public class Equatable : IEquatable { ... }
public class ClassName1 : Equatable {}
public class ClassName2 : Equatable {}
public class ClassName3 : Equatable {}
public class ClassName4 : Equatable {}
NOTE: All of the code snippet suggestions seem like they would be a maintenance nightmare down the road if you needed to change something.
I would suggest you to create code snippet yourself, that will be quick and easy.
精彩评论