gpt4 book ai didi

c# - 转换方法以使用任何枚举

转载 作者:行者123 更新时间:2023-11-30 17:44:16 24 4
gpt4 key购买 nike

我的问题:

我想将randomBloodType()方法转换为可以采用任何枚举类型的静态方法。我希望我的方法采用任何类型的枚举,无论是BloodType,DaysOfTheWeek等,然后执行以下所示的操作。

该方法的一些背景知识:

该方法当前基于分配给每个元素的值从BloodType枚举中选择一个随机元素。值较高的元素被拾取的可能性更高。

码:

    public enum BloodType
{
// BloodType = Probability
ONeg = 4,
OPos = 36,
ANeg = 3,
APos = 28,
BNeg = 1,
BPos = 20,
ABNeg = 1,
ABPos = 5
};

public BloodType randomBloodType()
{
// Get the values of the BloodType enum and store it in a array
BloodType[] bloodTypeValues = (BloodType[])Enum.GetValues(typeof(BloodType));
List<BloodType> bloodTypeList = new List<BloodType>();

// Create a list where each element occurs the approximate number of
// times defined as its value(probability)
foreach (BloodType val in bloodTypeValues)
{
for(int i = 0; i < (int)val; i++)
{
bloodTypeList.Add(val);
}
}

// Sum the values
int sum = 0;
foreach (BloodType val in bloodTypeValues)
{
sum += (int)val;
}

//Get Random value
Random rand = new Random();
int randomValue = rand.Next(sum);

return bloodTypeList[randomValue];

}


到目前为止我尝试过的是:

我试图使用泛型。他们大部分工作了,但是我无法将枚举元素转换为int值。我在下面提供了一段代码示例,该代码给我带来了问题。

    foreach (T val in bloodTypeValues)
{
sum += (int)val; // This line is the problem.
}


我也尝试使用Enum e作为方法参数。我无法使用此方法声明我的枚举元素数组的类型。

最佳答案

假设您的枚举值都是int类型的(如果它们是longshort或其他类型,则可以相应地进行调整):

static TEnum RandomEnumValue<TEnum>(Random rng)
{
var vals = Enum
.GetNames(typeof(TEnum))
.Aggregate(Enumerable.Empty<TEnum>(), (agg, curr) =>
{
var value = Enum.Parse(typeof (TEnum), curr);
return agg.Concat(Enumerable.Repeat((TEnum)value,(int)value)); // For int enums
})
.ToArray();

return vals[rng.Next(vals.Length)];
}


使用方法如下:

var rng = new Random();
var randomBloodType = RandomEnumValue<BloodType>(rng);




人们似乎在输入枚举中存在多个无法区分的枚举值的问题(我仍然认为上面的代码提供了预期的行为)。请注意,这里没有答案,甚至没有Peter Duniho的答案,也无法让您区分具有相同值的枚举条目,因此我不确定为什么将其视为任何潜在解决方案的指标。

但是,不使用枚举值作为概率的另一种方法是使用属性来指定概率:

public enum BloodType
{
[P=4]
ONeg,
[P=36]
OPos,
[P=3]
ANeg,
[P=28]
APos,
[P=1]
BNeg,
[P=20]
BPos,
[P=1]
ABNeg,
[P=5]
ABPos
}


上面使用的属性如下所示:

[AttributeUsage(AttributeTargets.Field, AllowMultiple = false)]
public class PAttribute : Attribute
{
public int Weight { get; private set; }

public PAttribute(int weight)
{
Weight = weight;
}
}


最后,这就是获取随机枚举值的方法:

static TEnum RandomEnumValue<TEnum>(Random rng)
{
var vals = Enum
.GetNames(typeof(TEnum))
.Aggregate(Enumerable.Empty<TEnum>(), (agg, curr) =>
{
var value = Enum.Parse(typeof(TEnum), curr);

FieldInfo fi = typeof (TEnum).GetField(curr);
var weight = ((PAttribute)fi.GetCustomAttribute(typeof(PAttribute), false)).Weight;

return agg.Concat(Enumerable.Repeat((TEnum)value, weight)); // For int enums
})
.ToArray();

return vals[rng.Next(vals.Length)];
}


(注意:如果此代码对性能至关重要,则可能需要对其进行调整并为反射数据添加缓存)。

关于c# - 转换方法以使用任何枚举,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29872327/

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