相关疑难解决方法(0)

为Nullable Enum添加约束

我正在编写一些枚举功能,并具有以下功能:

public static T ConvertStringToEnumValue<T>(string valueToConvert, bool isCaseSensitive)
{
    if (typeof(T).BaseType.FullName != "System.Enum" && typeof(T).BaseType.FullName != "System.ValueType")
    {
       throw new ArgumentException("Type must be of Enum and not " + typeof (T).BaseType.FullName);
    }

    if (String.IsNullOrWhiteSpace(valueToConvert))
      return (T)typeof(T).TypeInitializer.Invoke(null);

    valueToConvert = valueToConvert.Replace(" ", "");              

    if (typeof(T).BaseType.FullName == "System.ValueType")
    {
        return (T)Enum.Parse(Nullable.GetUnderlyingType(typeof(T)), valueToConvert, !isCaseSensitive);
    }

    return (T)Enum.Parse(typeof(T), valueToConvert, !isCaseSensitive);
}
Run Code Online (Sandbox Code Playgroud)

我称之为:

EnumHelper.ConvertStringToEnumValue<Enums.Animals?>("Cat");
Run Code Online (Sandbox Code Playgroud)

我现在想要将T的约束添加到Enum,例如(我从Stackoverflow文章中获得):where T : struct, IConvertible但是我遇到了问题,因为T需要能够获取可以为空的枚举.错误消息说:

类型'Enums.Animals?' 必须是非可空值类型才能在泛型类型或方法中将其用作参数"T"

有没有办法做到这一点,或者我需要依靠运行时检查我在方法内部?

谢谢大家!

c# enums nullable constraints

5
推荐指数
1
解决办法
955
查看次数

可以将泛型类型约束到枚举?

我有一个泛型类Foo<T>,我想约束T为一个enum类型.这可能在C#中吗?

我试过了

public class Foo<T> where T : enum   // COMPILATION ERROR
Run Code Online (Sandbox Code Playgroud)

但这种方法似乎只对工作classstruct.

同样,尝试约束T到基础enum类型也不起作用:

public class Foo<T> where T : int    // COMPILATION ERROR
Run Code Online (Sandbox Code Playgroud)

因为int不是类或接口.


编辑我现在意识到之前已经发布了类似的问题,最终可以删除这个问题.一个与我的问题更相关的问题,也包含与下面相同的答案,就是这个问题.

更新20189月13日在最新的次要C#版本7.3中,现在可以将泛型类型约束为Enum.有关详细信息,请参阅此处.

c# generics enums

4
推荐指数
1
解决办法
137
查看次数

如何声明一个泛型类型使用的枚举?

我想在父抽象类中声明以下内容:

  public abstract void RefreshDisplay<TView>(Enum value);
Run Code Online (Sandbox Code Playgroud)

然后将在子类中实现,如:

   public override void RefreshDisplay<RxViewModel>(RxViews view)
Run Code Online (Sandbox Code Playgroud)

其中RxViews是枚举,并从该枚举"查看"特定值.

直到运行时才会知道它来自的实际视图和枚举.

可以这样做吗?我很感激帮助.

编辑:我可能会问这个错误.TView不是枚举,而是从ViewModelBase继承的视图.(我不知道这是一个重复的问题?)谢谢.

编辑:我猜这是在4.5中修复的.任何想法如何在net 4.0中解决这个问题?

c# generics

4
推荐指数
1
解决办法
8679
查看次数

抽象类的继承使用另一个不是为property定义的Type

我创建了以下抽象类:

public abstract class AbstractClass
{
    public abstract string Name { get; set; }
    public abstract object Value { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

现在我想派生两个抽象类的类.我想使用enum而不是类型object.我的派生类看起来像这样:

头等舱:

public class InheritanceClass1:AbstractClass
{
    public override string Name { get; set; }
    public override FirstEnum Value { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

二等:

public class InheritanceClass2 : AbstractClass
{
    public override string Name { get; set; }
    public override SecondEnum Value { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

我的代码中显示错误,属性值的类型不是object.我试着使用new-keyword而不是override …

c# inheritance abstract-class

4
推荐指数
1
解决办法
141
查看次数

如何在 .NET Standard 中为通用枚举类型设置枚举标志?

我想使用 .NET Standard 实现以下方法:

public static void SetFlag<TEnum>(ref TEnum value, TEnum flag)
    where TEnum : Enum
Run Code Online (Sandbox Code Playgroud)

我花了几个小时试图实现这一目标:

  • |对于像 s 这样的基本类型来说,通过反射获取运算符似乎是不可能的enum
  • 使用dynamic需要引用额外的包 ( Microsoft.CSharp.RuntimeBinder),但我希望我的库保持纯粹的 .NET 标准符合。

我最新的想法是手动比较 TEnum每个有效的枚举类型{byte , sbyte, short, ushort, int, uint, long, ulong}。但这感觉真的很奇怪而且肮脏:

try
{
    var v = (byte)(object)value | (byte)(object)flag;
    value = (TEnum)(object)v;
    return;
}
catch (InvalidCastException) { }

try
{
    var v = (int)(object)value | (int)(object)flag; …
Run Code Online (Sandbox Code Playgroud)

.net c# reflection enums .net-standard

4
推荐指数
1
解决办法
1012
查看次数

为什么在 C# 中对通用枚举扩展方法使用“where T: struct”?

我已经看到 C# 中用于枚举的通用扩展方法的示例where T: struct,还有另一个使用where T: IComparable. 例如,在前一种情况下:

public static class EnumExtensionMethods
{
  public static string Description<T>(this T enumValue) where T : struct
  {
    // ...
  }
}
Run Code Online (Sandbox Code Playgroud)

我很困惑为什么约束要求该类型T必须是struct. 我希望它是where T : Enum。谁可以给我解释一下这个?作为奖励项目,也许还可以解释为什么IComparable在某些示例中也使用。

FWIW,我对此进行了研究。我可以找到关于为什么IComparable使用的解释,例如在这个问题中,但它似乎不是决定性的,它们也没有解释为什么struct结合使用。

c#

4
推荐指数
1
解决办法
258
查看次数

如何在泛型方法中获取枚举的数据值?

由于这个问题,我设法弄清楚如何限制我的通用方法仅接受枚举。

现在,我尝试创建一个通用方法,以便可以将下拉列表绑定到我选择的任何枚举,在下拉列表中显示描述,其值等于枚举值的数值

public static object EnumToDataSource<T>() where T : struct, IConvertible {
  if (!typeof(T).IsEnum) // just to be safe
    throw new Exception(string.Format("Type {0} is not an enumeration.", typeof(T)));
  var q = Enum.GetValues(typeof(T)).Cast<T>()
    .Select(x => new { ID = DataUtil.ToByte(x), Description = x.ToString() }) // ToByte() is my own method for safely converting a value without throwing exceptions
    .OrderBy(x => x.Description);
  return q;
}
Run Code Online (Sandbox Code Playgroud)

看起来不错,但 ToByte() 始终返回 0,即使我的枚举已显式设置值,如下所示:

public enum TStatus : byte {
  Active = 1,
  Inactive …
Run Code Online (Sandbox Code Playgroud)

c# linq generics enums

3
推荐指数
1
解决办法
4291
查看次数

接受多个枚举类型的方法

我有一个3类枚举类

我想有一个方法,可以将所有3个枚举作为参数,并获取枚举的整数值.

public enum Enum1
{
    Fire = 0,
    Hour_24 = 1,
    Key_Switch = 2,
    Follower = 3,
    Entry_Delay1 = 4,
    Entry_Delay2 = 5,
    Intertior = 6,
    Local_Only = 7,
}

public enum Enum2
{
    Faulted = 0,
    Tampered = 1,
    Trouble = 2,
    Bypassed = 3,
    Inhibited = 4, 
    Low_Battery = 5,
    Loss_Supervision = 6,
    Reserved,
    Alarm_Memory = 8,
    Bypass_Memory = 9
}

private void BuildMessage ()
{
     List<Enum1> Enum1List = new List<Enum1>();
     FillBits(Enum1List);  // => Here I get …
Run Code Online (Sandbox Code Playgroud)

c# enums

3
推荐指数
1
解决办法
2195
查看次数

C# - 使用通用枚举(或控制列表的替代方法)

我正在为游戏编写一个寻路算法,但试图保持它的通用性,以便它可以在未来的应用程序中使用.

我有一个Node类,它包含X,Y和"PassableType".

NodeGrid类存储一个节点数组,包含它们如何连接的图形信息,然后有一个FindAStarPath()函数,该函数将"PassableTypes"作为参数StartNode,EndNode和params.

我的问题是确定"PassableType"应该具有什么类型.

理想情况下我想要的是能够使用通用枚举 - 即每个游戏定义的限制列表.Node将保存该列表中的单个元素,以说明它是什么路径类型(当前游戏可能使用Path,Grass,Wall等)

因此,当实体尝试路径时,它提供路径查找功能,其类型被视为"可通过".所以男人可以使用

FindAStarPath(CurrentNode, DestinationNode, "Path", "Floor", "Door");
Run Code Online (Sandbox Code Playgroud)

但是汽车可能会使用

FindAStarPath(StartNode, EndNode, "Road");
Run Code Online (Sandbox Code Playgroud)

我的问题是我无法弄清楚如何让NodeGrid采用Generic枚举或等效逻辑.

目前我已经接受了字符串,但这意味着我
每次使用它时都必须编写MyEnum.Road.ToString().

理想情况下,我想做点什么

NodeGrid<MyEnum> CurrentNodeGrid = new NodeGrid<MyEnum>()
Run Code Online (Sandbox Code Playgroud)

然后Nodes会将MyEnum作为passableType,路径寻找函数也是如此,因此每个游戏都有一组不同的tile类型用于路径.

但我不能将NodeGrid定义为:

public class NodeGrid<T> where T:enum
Run Code Online (Sandbox Code Playgroud)

为清楚起见,使用此枚举的唯一部分路径查找功能是这个(包含在Node中):

    public bool IsPassable(string[] passableTypes)
    {
        for (var i = 0; i < passableTypes.Count(); i++)
        {
            if (this.PassableType == passableTypes[i]) return true;
        }
        return false;
    }
Run Code Online (Sandbox Code Playgroud)

谢谢Haighstrom

c# generics enums

3
推荐指数
1
解决办法
200
查看次数

如何将Nullable T作为返回类型?

我有一个方法,我用来将字符串转换为通用枚举.可以将结果值分配给可以为空的字段.

对于不可为空的情况,以下工作正常,但我无法弄清楚如何正确调整它以允许可为空的返回类型,比如在参数为null的情况下,或者实际上如何允许返回类型可能是null或不可为空(也许这是不可能的?).每置换Nullable<T>T?,我试过仍然导致的返回值和方法名称都被红色squiggleys

private static T ConvertStringToEnumValue<T>(string value)
{
    // Converts string to a given enum-type T value.
    T EnumValue;
    try
    {
        EnumValue = (T)Enum.Parse(typeof(T), value);
        if (!Enum.IsDefined(typeof(T), EnumValue))
        {
            return default(T); // 0 for enum
        }
    }
    catch (Exception e)
    {
        return default(T); // 0 for enum
    }
    return EnumValue;
}
Run Code Online (Sandbox Code Playgroud)

c# generics enums nullable

2
推荐指数
1
解决办法
529
查看次数