通过枚举和字段执行'task',方法是检查'T'类型,并将其自动推断到任务中



我遇到了一个我无法解决的问题。我有一IReadOnlyList类,每个类都有一堆字段。这些字段的名称(变量名称(与枚举列表相同。认为对于存在的每个字段,也存在一个具有完全相同名称的枚举(因此object helloHi具有等效的enum something { helloHi }(。

我试图做的是比较两个字段名称。如果它们相同,请对它们执行功能。问题在于该函数需要从变量推断出T,并且由于反射无法在没有某种形式的强制转换的情况下拉动该"T",因此它不会继续。

这是代码:

public class Something() {
[BackgroundTask]
private void load(Overlay param_1, Config param_2) {
Children = new Drawable[] // is the IReadOnlyList
{
SomethingClass(param_1),
AnotherClass(param_2)
}
performTask(this, param_2);
}
}
public class Config {
public void task<U>(SomeEnums se, ValueType<U> value) // do the task
}
public class SomethingClass {
ValueType<double> someDouble = new ValueType<double>();
ValueType<int> someInt = new ValueType<int>();
public SomethingClass(Overlay overlay) //...
}
public enum SomeEnums {
someDouble,
someInt,
}
void performTask(Something the_class, Config the_config) {
// ... for each field within the_class, do (uses reflection)
field => {
foreach (SomeEnums enums in Enum.GetValues(typeof(SomeEnums)))
{
if (field.Name == enums.ToString()) {
the_config.task(enums, field.GetValue(null)); // cant infer 'U' from an 'object'
}
}
}
}

从技术上讲,我可以只在已知和可见类型的类中执行config.task,但我更愿意从这里自动化它,这样它就不需要每次创建新变量时进行 2-3 次更改。

我知道的策略之一是在performTask内执行if检查,如下所示:

// performTask, field =>, foreach
{
if (field.FieldType == ValueType<double>)
config.task(enums, (ValueType<double>)field.GetValue(null));
} //etc

但是,我不喜欢这种方法。如果我创建了更多的ValueType<>并且它们还没有被检查,它只需要引入越来越多的检查。有没有更好的方法来执行我想要的?

正如我在评论中提到的,我不太清楚你真正想做什么。 但是,这里有一些代码可以帮助您弄清楚。

它使用反射来获取对象的字段,查看这些字段的名称(将它们与与enum类型关联的值/名称进行比较(并比较值。 我与整数 5 进行了比较,但您可以与任何东西进行比较(但是,如果将整数类型与int以外的其他内容进行比较,则整数类型的 IComparable.CompareTo 的实现似乎会抛出,所以我检查(。 由于您知道所有内容的类型,因此很容易检查(您不必与固定Type进行比较,您可以使用GetType()返回的内容(。

我从一些辅助类型开始:

public enum SomeEnums {
SomeDouble,
SomeInt,
}
public class Class1 {
public int SomeInt = 5;
public double SomeDouble = 3.14;
}
public class Class2 {
public int SomeInt = 5;
public double SomeDouble = 6.28;
}

然后添加以下内容:

public class EnumFields {
public List<object> Objects = new List<object> {
new Class1(),
new Class2(),
};
public void PerformTask () {
var enumVals = Enum.GetNames(typeof(SomeEnums));
foreach (var obj in Objects) {
var objType = obj.GetType();
var fieldInfos = objType.GetFields(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public);
//right around here I get lost.  You have a list of objects (which has two instances right now), 
//What are you comparing, that every field named SomeInt has the same value??
//Anyway, here's some code that should help you
foreach (var fieldInfo in fieldInfos) {
if (enumVals.Contains(fieldInfo.Name)) {
var fieldObj = fieldInfo.GetValue(obj);
var isSame = false;
if (fieldObj.GetType() == typeof(int)) {
var comparable = (IComparable)fieldObj;
var same = comparable.CompareTo(5);
isSame = (same == 0);
}
Debug.WriteLine($"Field: {fieldInfo.Name} of instance of {obj.GetType().Name} (Value: {fieldObj}) is equal to 5:{isSame}");
}
}
}
}
}

当我实例化一个EnumFields对象并对其调用PerformTask时,我在输出中看到以下内容:

Field: SomeInt of instance of Class1 (Value: 5) is equal to 5:True
Field: SomeDouble of instance of Class1 (Value: 3.14) is equal to 5:False
Field: SomeInt of instance of Class2 (Value: 5) is equal to 5:True
Field: SomeDouble of instance of Class2 (Value: 6.28) is equal to 5:False

这应该会让你大部分时间到达那里。 我知道它没有回答你的问题。 如果我能弄清楚你在问什么,它可能会。

相关内容

  • 没有找到相关文章

最新更新