【问题标题】:How to refer to an enum in the actual class rather than the base class in C#如何在实际类中引用枚举而不是 C# 中的基类
【发布时间】:2018-09-04 13:23:19
【问题描述】:

我在这方面遇到了麻烦,因为我也很难正确地制定它。让谷歌搜索变得更加困难。我会尽量解释清楚。我已经简化了代码,以便更清楚我的问题是什么

我有一个抽象类,它的方法和属性被所有以此为基类的类使用:

public abstract class TheBaseClass{

    //some properties here

    public enum MyEnum{} // this one every class has. It is pretty much empty here. Not sure if this is best practice.

    //some methods here
}

那么有很多基于这个的类:

public SpecializedClass : TheBaseClass{

    //some more properties here

    public new enum MyEnum{} //every single class has a different enum

    //some more methods here
}

现在,在代码的其他地方,我有一个方法

public void MyMethod(TheBaseClass baseclassobject){

    //do stuff
    var usedforsomething = ((TheBaseClass.MyEnum)i).ToString() //i being an int. This is used to name something in a plot.
    //do more stuff
}

使用 TheBaseClass 作为该方法的参数的原因是,在我有很长的代码之前,我的代码执行 mymethod 对从 TheBaseClass 派生的每个类所做的事情。重复代码不好,所以我改用这个方法,想用参数 SpecializedClass 调用它(以及许多其他类似的类)。问题是,当调用 TheBaseClass.MyEnum 时,我自然会得到 BaseClass 的枚举,而不是来自 SpecializedClass 的枚举。我一直在尝试如何在方法中获得正确的枚举,无论我给它什么基类对象,但似乎找不到解决方案。

如何获取任何类 baseclassobject 的枚举?我尝试了一些不同的方法,但似乎不起作用。 我认为的问题是枚举不是我可以从对象调用的属性或方法,而是需要调用ClassName.MyEnum,我在方法中没有className。

一种解决方案可能是为每个类类型创建一个方法,并将该特定的类类型作为参数,但这似乎有很多重复的代码。

例如,如果我有 50 个不同的派生类,例如 SpecializedClass

【问题讨论】:

  • 但是如果使用不同的枚举,usedforsomething 的工作方式不会有很大不同。看看你打算如何使用它会很有趣。
  • 我已经更正了一点。在这个特定的上下文中,它仅用于提取位置 i 的枚举被调用的内容。
  • 您应该避免遮蔽 (new) 类中的任何元素。这是通往毁灭和毁灭的捷径。你的设计应该 100% 避免它。
  • @Enigmativity,我只是在做这个方法的时候加的。通常我在 TheBaseClass 中没有 MyEnum,但在每个专业类中都有一个自定义的 MyEnum。如果它更好,我可以这样做。但我仍然有同样的问题
  • @Marshall - baseclassobject.GetType().GetNestedType("MyEnum").GetEnumValues() 能拉近你的距离吗?

标签: c# inheritance enums abstract-class


【解决方案1】:

我认为反射是你唯一的选择。

var usedforsomething = 
      baseclassobject
       .GetType()
       .GetNestedType(nameof(TheBaseClass.MyEnum))
       .GetEnumName(i);

但也许更好的解决方案是在您的子类必须覆盖的基类中添加一个抽象函数 GetName

public abstract class TheBaseClass
{

    public enum MyEnum {a,b }

    public abstract string GetName(int value);
}

public class SpecializedClass : TheBaseClass
{

    public new enum MyEnum {c,d }

    public override string GetName(int value)
    {
        return ((MyEnum)value).ToString();
    }
}

你可以这样做:

var usedforsomething = baseclassobject.GetName(i);

您可以避免反射以及对使用特定名称 MyEnum 声明枚举的子类的依赖。

【讨论】:

    【解决方案2】:

    我可能对您的理解有误,但是您是否尝试在MyMethod 中做一些反射来获取必要的枚举类型:

    public static void MyMethod(TheBaseClass baseclassobject)
    {
        Type enumType = baseclassobject.GetType().GetNestedType("MyEnum");
        var usedforsomething = Enum.GetName(enumType, 1);
        Console.WriteLine(usedforsomething);
    }
    

    【讨论】:

    • OP 的MyMethod 表明希望使用int i 来索引enum 值。你忽略了这个
    • 我只是想提供一个工作示例。原代码中没有int i声明。
    • OP 很清楚:var usedforsomething = ((TheBaseClass.MyEnum)i).ToString() //i being an int. This is used to name something in a plot.
    • 很公平。请澄清我避免使用int i 的原因。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-06
    • 2010-10-25
    • 1970-01-01
    • 2022-11-17
    • 1970-01-01
    相关资源
    最近更新 更多