1

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?

3
  • 1
    Why wouldn't normal class inheritance work? Then the only thing you would repeat would be the constructor. Commented Jan 6, 2010 at 14:55
  • I don't want classes of one type like this to be comparable with classes of another type like this. Inheritance can handle GetHashCode, ToString and Description, but not Equals. Commented Jan 6, 2010 at 14:57
  • I'm not saying this applies specifically to your situation, but, anytime I think "How can I quickly duplicate this X times" it raises a big red flag telling me to reconsider my design. Usually, I try to remove duplication rather than automate it. Commented Jan 6, 2010 at 15:20

5 Answers 5

12

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.

Sign up to request clarification or add additional context in comments.

3 Comments

Supported in express by any chance?
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
Daniel, yes, you can do this in Express with some configuration. See this question: stackoverflow.com/questions/786734/…
3

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

Comments

2

Have you considered code snippets?

Comments

1

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.

Comments

0

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.