views:

123

answers:

5

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(other.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?

+2  A: 

Have you considered code snippets?

CesarGon
A: 

I would suggest you to create code snippet yourself, that will be quick and easy.

Prashant
+11  A: 

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.

Craig Stuntz
Supported in express by any chance?
Daniel Straight
If T4 will get VS to generate the source files for you I'm going to have to stop using my homebrew c# tool to create simple codefiles now! Thx for the example Craig
Tj Kellie
Daniel, yes, you can do this in Express with some configuration. See this question: http://stackoverflow.com/questions/786734/subsonic-asp-net-mvc-sample-in-visual-web-developer-express
Craig Stuntz
+1  A: 

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.

Alan Jackson
+2  A: 

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> { ... }
Arjan Einbu