gpt4 book ai didi

c# - 泛型、枚举和自定义属性——这可能吗?

转载 作者:太空狗 更新时间:2023-10-29 17:56:18 26 4
gpt4 key购买 nike

抱歉代码量太大,但这样解释起来更容易。

我有一个自定义属性 CustomUserData 实现如下:

public class CustomUserData : Attribute
{
public CustomUserData(object aUserData)
{
UserData = aUserData;
}
public object UserData { get; set; }
}

以及枚举的扩展方法:

public static class EnumExtensions
{
public static TAttribute GetAttribute<TAttribute>(this Enum aValue) where TAttribute : Attribute
{
Type type = aValue.GetType();
string name = Enum.GetName(type, aValue);
return type.GetField(name)
.GetCustomAttributes(false)
.OfType<TAttribute>()
.SingleOrDefault();
}

public static object GetCustomUserData(this Enum aValue)
{
CustomUserData userValue = GetAttribute<CustomUserData>(aValue);
return userValue != null ? userValue.UserData : null;
}
}

然后我有一个帮助程序类,它序列化/反序列化一个枚举,该枚举具有与其关联的自定义数据,如下所示:

public static class ParameterDisplayModeEnumListHelper
{
public static List<ParameterDisplayModeEnum> FromDatabase(string aDisplayModeString)
{
//Default behaviour
List<ParameterDisplayModeEnum> result = new List<ParameterDisplayModeEnum>();

//Split the string list into a list of strings
List<string> listOfDisplayModes = new List<string>(aDisplayModeString.Split(','));

//Iterate the enum looking for matches in the list
foreach (ParameterDisplayModeEnum displayModeEnum in Enum.GetValues(typeof (ParameterDisplayModeEnum)))
{
if (listOfDisplayModes.FindIndex(item => item == (string)displayModeEnum.GetCustomUserData()) >= 0)
{
result.Add(displayModeEnum);
}
}

return result;
}

public static string ToDatabase(List<ParameterDisplayModeEnum> aDisplayModeList)
{
string result = string.Empty;

foreach (ParameterDisplayModeEnum listItem in aDisplayModeList)
{
if (result != string.Empty)
result += ",";
result += listItem.GetCustomUserData();
}

return result;
}
}

然而,这是特定 ParameterDisplayModeEnum 并且我有一堆枚举需要以这种方式处理以进行序列化/反序列化,所以我更希望有一个通用的这样作为:

public static class EnumListHelper<TEnum>
{
public static List<TEnum> FromDatabase(string aDisplayModeString)
{
//Default behaviour
List<TEnum> result = new List<TEnum>();

//Split the string list into a list of strings
List<string> listOfDisplayModes = new List<string>(aDisplayModeString.Split(','));

//Iterate the enum looking for matches in the list
foreach (TEnum displayModeEnum in Enum.GetValues(typeof (TEnum)))
{
if (listOfDisplayModes.FindIndex(item => item == (string)displayModeEnum.GetCustomUserData()) >= 0)
{
result.Add(displayModeEnum);
}
}

return result;
}

public static string ToDatabase(List<TEnum> aDisplayModeList)
{
string result = string.Empty;

foreach (TEnum listItem in aDisplayModeList)
{
if (result != string.Empty)
result += ",";
result += listItem.GetCustomUserData();
}

return result;
}
}

然而,这将不起作用,因为无法调用 GetCustomUserData()。有什么建议么?我无法更改自定义属性的使用或枚举的使用。我正在寻找一种通用的方法来进行序列化/反序列化,而不必每次都编写一个具体的列表帮助器类。

感谢所有建议。

最佳答案

试试这段代码:

public static class EnumListHelper
{
private static void EnsureIsEnum<TEnum>()
{
if (!typeof(TEnum).IsEnum)
throw new InvalidOperationException(string.Format("The {0} type is not an enum.", typeof(TEnum)));
}

public static List<TEnum> FromDatabase<TEnum>(string aDisplayModeString)
where TEnum : struct
{
EnsureIsEnum<TEnum>();
//Default behaviour
List<TEnum> result = new List<TEnum>();

//Split the string list into a list of strings
List<string> listOfDisplayModes = new List<string>(aDisplayModeString.Split(','));

//Iterate the enum looking for matches in the list
foreach (Enum displayModeEnum in Enum.GetValues(typeof(TEnum)))
{
if (listOfDisplayModes.FindIndex(item => item == (string)displayModeEnum.GetCustomUserData()) >= 0)
{
result.Add((TEnum)(object)displayModeEnum);
}
}

return result;
}

public static string ToDatabase<TEnum>(List<TEnum> aDisplayModeList)
where TEnum : struct
{
EnsureIsEnum<TEnum>();
string result = string.Empty;

foreach (var listItem in aDisplayModeList.OfType<Enum>())
{
if (result != string.Empty)
result += ",";
result += listItem.GetCustomUserData();
}

return result;
}
}

var fromDatabase = EnumListHelper.FromDatabase<TestEnum>("test");
EnumListHelper.ToDatabase(fromDatabase);

更新 0

需要明确的是,因为我们不能将泛型限制为枚举,所以我们应该检查类型 TEnum 是否为枚举,如果不是则抛出异常。当我们使用 FromDatabase 方法时,我们知道 TEnum 是枚举,我们可以编写此代码将枚举转换为指定的 TEnum:

result.Add((TEnum)(object)displayModeEnum)

ToDatabase 方法中我们也知道 TEnum 是枚举,我们可以编写这段代码将 TEnum 转换为 Enum 类型:

aDisplayModeList.OfType<Enum>()

关于c# - 泛型、枚举和自定义属性——这可能吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18117417/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com