【问题标题】:Why do I have to specify type argument when using enum in generic class为什么在泛型类中使用枚举时必须指定类型参数
【发布时间】:2015-04-14 15:05:35
【问题描述】:

我有以下示例代码。为什么我必须为 T 指定一个类型?这是我可以利用的东西吗?我不明白为什么枚举定义取决于类型参数?根据类型,枚举的内容如何成为其他内容?因此,在我的语法糖的支持下,我想保留类型的定义。

public class SomeGenericClass<T>
{
    public enum InitialisationMode
    {
        UseDefaultValues,
        DoOtherThings
    }

    public SomeGenericClass(InitialisationMode initMode = InitialisationMode.UseDefaultValues)
    {

    }
}

public class SomeOtherClass
{
    public void DoAction()
    {
        //Why do I have to specify the generic type arguments when using the enum value?
        var genericClass = new SomeGenericClass<int>(SomeGenericClass<int>.InitialisationMode.DoOtherThings);
        //I Would expect to be able to use the enum like the line below:
        genericClass = new SomeGenericClass<int>(SomeGenericClass.InitialisationMode.DoOtherThings);
    }
}

我知道我可以通过做这样的事情来解决这个问题,或者将枚举放在一个作用域上:

public class SomeGenericClass<T>
{
    public SomeGenericClass(SomeGenericClass.InitialisationMode initMode = SomeGenericClass.InitialisationMode.UseDefaultValues)
    {

    }
}

public abstract class SomeGenericClass
{
    public enum InitialisationMode
    {
        UseDefaultValues,
        DoOtherThings
    }
}

public class SomeOtherClass
{
    public void DoAction()
    {
        //I Would expect to be able to use the enum like the line below:
        var genericClass = new SomeGenericClass<int>(SomeGenericClass.InitialisationMode.DoOtherThings);
    }
}

【问题讨论】:

  • T 没有在任何地方使用。如果不使用泛型参数,那么声明它的原因是什么?
  • 在需要公开使用枚举时,很好奇在类中声明枚举的原因。为什么不在课堂之外声明它并避免这个问题?
  • 嗯,他们是规则。为什么不直接解决问题并将枚举类型移到课堂之外?
  • @haim770 由于此代码的核心目的是展示如何引用该枚举,所有其他代码都掩盖了代码的示例性目的。

标签: c# .net generics enums


【解决方案1】:

因为您的枚举存在于该类中,并且有可能(如果不是很实用)使该枚举对于不同的类型有所不同:

class Program
{
    static void Main(string[] args)
    {
        var sgc = new SomeGenericClass<string>("asdf");

        var sgc2 = new SomeGenericClass<int>(1);

        var sgc3 = new SomeNonGenericChild("asdf2");
        Console.ReadKey();
    }
}

public class SomeGenericClass<T>
{
    public enum InitialisationMode
    {
        UseDefaultValues,
        DoOtherThings = 3
    }


    public SomeGenericClass(T blah, InitialisationMode initMode = InitialisationMode.UseDefaultValues)
    {

        Console.WriteLine(blah.GetType().Name + "; " + initMode);
    }
}

public class SomeNonGenericChild : SomeGenericClass<string>
{
    public new enum InitialisationMode
    {
        UseDefaultValues,
        DoEvenMoreThings
    }

    public SomeNonGenericChild(string blah, InitialisationMode initMode= InitialisationMode.DoEvenMoreThings) : base(blah)
    {

        Console.WriteLine(blah.GetType().Name + "; " + initMode);
    }
}

要实现您想要的语法,您可以执行以下操作:

namespace SomeNamespace
{
    public enum InitialisationMode
    {
        UseDefaultValues,
        DoOtherThings
    }
    public class SomeGenericClass<T>
    {

        public SomeGenericClass(InitialisationMode initMode = InitialisationMode.UseDefaultValues)
        {

        }
    }
}

【讨论】:

  • 是的,谢谢你的例子,我明白了。您能否详细说明(可能举例?)您所说的内容:and it would be possible (if not very practical) to have that enumeration be different for different types.
  • 我刚刚发布的示例是尽可能接近的。这样做可能有更好/更复杂的方法,但关键是枚举定义可以在此处针对不同的实例进行更改。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-05-23
相关资源
最近更新 更多