如何在 C# 中生成这样的类?

发布于 2024-08-16 23:32:21 字数 854 浏览 8 评论 0原文

我在一个项目中有多个类,除了类名之外,它们完全相同。基本上,它们代表在运行时从配置文件加载的美化枚举。这些类看起来像这样:

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 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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

执手闯天涯 2024-08-23 23:32:21

我建议使用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" };
#>

VS 将为您生成一个源文件。当您需要新类时,只需添加到数组 classes 中即可。

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.

握住我的手 2024-08-23 23:32:21

您可以将继承与泛型一起使用吗?

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; }
}

然后你可以像这样继承:

public class ClassName1 : MyBase<ClassName1> { ... }
public class ClassName2 : MyBase<ClassName2> { ... }
public class ClassName3 : MyBase<ClassName3> { ... }

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> { ... }
梦晓ヶ微光ヅ倾城 2024-08-23 23:32:21

您是否考虑过代码片段

Have you considered code snippets?

哥,最终变帅啦 2024-08-23 23:32:21

如果类确实完全相同,您可以使用继承吗?代码量非常小,并且不需要任何额外的前/后处理。

public class Equatable : IEquatable { ... }

public class ClassName1 : Equatable {}
public class ClassName2 : Equatable {}
public class ClassName3 : Equatable {}
public class ClassName4 : Equatable {}

注意:如果您需要更改某些内容,所有代码片段建议似乎都将是维护过程中的噩梦。

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.

怪异←思 2024-08-23 23:32:21

我建议您自己创建代码片段,这样既快速又简单。

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文