Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/321.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在不知道枚举类型的情况下将枚举基础值转换为字符串_C#_Enums - Fatal编程技术网

C# 在不知道枚举类型的情况下将枚举基础值转换为字符串

C# 在不知道枚举类型的情况下将枚举基础值转换为字符串,c#,enums,C#,Enums,我有一个方法,它获取一个对象并以字符串格式返回它,根据类型的不同,返回一些内容。例如: ConvertObjectToSQL(1); // "1" ConvertObjectToSQL("Foo"); // "'Foo'" ConvertObjectToSQL(DateTime.Now); // "'2017/02/22 00:00:00'" 当我向该方法提供枚举时,就会出现问题。我希望我的方法的作用就像我为它提供了枚举基础类型一样。当然,我的方法是在我不可能知道枚举类型的上下文中调用的 首先

我有一个方法,它获取一个对象并以字符串格式返回它,根据类型的不同,返回一些内容。例如:

ConvertObjectToSQL(1); // "1"
ConvertObjectToSQL("Foo"); // "'Foo'"
ConvertObjectToSQL(DateTime.Now); // "'2017/02/22 00:00:00'"
当我向该方法提供枚举时,就会出现问题。我希望我的方法的作用就像我为它提供了枚举基础类型一样。当然,我的方法是在我不可能知道枚举类型的上下文中调用的

首先,以下是我所做的:

private string ConvertObjectToSQL(object obj)
{
    if (obj == null)
    {
        return "NULL";
    }
    else if (obj is DateTime)
    {
        return "'" + obj.ToString() + "'";
    }
    else if (obj is string)
    {
        return "'" + obj.ToString().Replace("'", "''") + "'";
    }

    return obj.ToString();
}
但如果我的枚举是:

enum FooEnum : int { Foo = 0, Bar = 1 }
如果需要:

ConvertObjectToSQL(FooEnum.Foo); // "0"
ConvertObjectToSQL(FooEnum.Bar); // "1"
但它实际上返回:

ConvertObjectToSQL(FooEnum.Foo); // "Foo"
ConvertObjectToSQL(FooEnum.Bar); // "Bar"
因此,如果我做这项工作,我会得到一个新的else:

else if (obj is Enum)
{
    var baseType = Enum.GetUnderlyingType(obj.GetType());
    return Convert.ChangeType(obj, baseType).ToString();
}

我的问题是:我能在这里避免反射吗?因为这个方法被调用了很多次。

因为
枚举
实现了
IConvertable
,我们可以将它转换成
十进制
(它将覆盖所有整数类型的大小),然后转换成
字符串

private string ConvertObjectToSQL(object obj)
{
    if(obj is Enum)
    {
        return Convert.ToDecimal(obj).ToString();
        //return ((Enum)obj).ToString("D"); Or this
    }
    return "";
}

您可以创建一个委托来获取基础类型值并缓存它

''' <summary>
''' Caches an enum underlying value getter delegate.
''' </summary>
''' <typeparam name="TEnum">Enum type</typeparam>
Public Class CachedEnumUnderlyingValueAccess(Of TEnum)
    Private Shared underlyingTypeValueGetter As Func(Of TEnum, Object) = CreateUnderlyingTypeValueGetter()

    Private Shared Function CreateUnderlyingTypeValueGetter()
        Dim enumUnderlyingType As Type = [Enum].GetUnderlyingType(GetType(TEnum))
        Dim enumParameter As ParameterExpression = Expression.Parameter(GetType(TEnum))
        'Convert the enum parameter to its underlying type, then convert it to an Object
        Dim conversionExpression As Expression(Of Func(Of TEnum, Object)) = Expression.Lambda(Expression.Convert(Expression.Convert(enumParameter, enumUnderlyingType), GetType(Object)), enumParameter)
        Return conversionExpression.Compile()
    End Function

    Public Shared Function GetEnumUnderlyingValue(val As TEnum) As Object
        Return underlyingTypeValueGetter.Invoke(val)
    End Function
End Class
“”
''缓存枚举基础值getter委托。
''' 
''枚举类型
公共类CachedEnumUnderingValueAccess(共十个)
私有共享UnderlineTypeValueGetter作为Func(共十个,对象)=CreateUnderlineTypeValueGetter()
私有共享函数CreateUnderlineyTypeValueGetter()
Dim EnumUnderlyngType作为类型=[Enum]。GetUnderlyngType(GetType(TEnum))
Dim enumParameter作为ParameterExpression=Expression.Parameter(GetType(TEnum))
'将枚举参数转换为其基础类型,然后将其转换为对象
Dim conversionExpression As Expression(Of Func(Of TEnum,Object))=Expression.Lambda(Expression.Convert(Expression.Convert(enumParameter,EnumUnderlineType),GetType(Object)),enumParameter)
返回conversionExpression.Compile()
端函数
作为对象的公共共享函数GetEnumUnderlyingValue(val为TEnum)
返回underlineTypeValueGetter.Invoke(val)
端函数
末级

试试
ConvertObjectToSQL(((int)FooEnum.Foo).toString())
@leaming\u Dev:如果枚举不是基于
int
…@leaming\u Dev:正如我所说:
我的方法是在我不可能知道枚举类型的上下文中调用的。正如@Chris所说,枚举不一定基于int。我必须在这里指出一个问题,尽管您可能根本不应该这样做,但您似乎是通过连接片段来构造SQL,您可能需要研究使用参数。您可以根据类型来制作委托并缓存这些委托,这似乎要稍微快一点,不是太快,而是稍微快一点。这不起作用,因为我不知道枚举的基本类型。在我的示例中,我选择int,但它可以是
char
,例如,在IL中基于
char
的枚举合法吗?C#只允许数值整数类型。你想要返回数值吗?他已经说过他想要的,他想要数值作为字符串,不管int使用哪种基础类型,int可以基于byte、sbyte等,在这种情况下,转换为
(int)
将失败。为什么不使用枚举字符串格式说明符“D”?