gpt4 book ai didi

c# - 如何调用具有结构约束的方法到未知结构

转载 作者:太空狗 更新时间:2023-10-30 01:18:18 25 4
gpt4 key购买 nike

问题很简单:我正在使用反射来获取值。然后,如果它是一个 struct,我将调用一个方法 FooStruct,否则 FooClass:

Type type = x.GetType();
foreach (var fieldInfo in type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic))
{
var val = fieldInfo.GetValue(value);
object obj = type.IsValueType ? val.FooStruct() : val.FooClass();
fieldInfo.SetValue(x, obj);
}

问题是 FooStruct 有一个约束:

public static T FooStruct<T>(this T value) where T : struct
{
//...
}

所以问题是:是否可以为包含装箱结构实例而不进行反射的对象调用具有 struct 约束的方法?

最佳答案

我很乐意被另一个答案证明是错误的,但我认为如果不更多地进行反射(reflection),这是不可能的。请参阅下文进一步了解让我怀疑这一点的原因。有关基于反射的解决方案,请参阅答案的结尾。

实用建议:我会简单地放弃对你的 FooStruct 的约束和 FooClass方法,另外:

  • 要么让它们成为非通用的,要么接受类型为 object 的参数(这就是 val 被声明为,无论如何)。如果这些方法只被传递,那么让这些方法成为通用的就没有任何优势 object ;

  • 或投 val来自 objectT在调用之前 FooStruct/FooClass .

为什么似乎无法完成您的要求?您正在尝试转换静态类型的表达式 object (即 val )到静态类型的东西 <T> where T : struct<T> where T : class (为了在这样的 T 上调用相应的扩展方法)。也就是说,您正试图在 foreach 中动态引入一个新的类型变量。环形。不幸的是,引入类型变量的唯一方法是提前声明它,即作为一些泛型类型参数 T在方法的签名中;然后,不是您的方法内部的代码可以选择它代表的实际类型——是调用的代码决定T .

基于反射的解决方案:

// determine which method ought to be called based on `val`'s run-time type.
// (for C# 6 and later, use the `nameof` operator instead of hard-coding method names)
Type type = val.GetType();
string fooName = type.IsValueType ? "FooStruct" : "FooClass";

// bind to the generic method and supply the type argument for it:
// (I'm assuming that your extension methods are defined in `FooMethodsClass`.)
MethodInfo fooOpen = typeof(FooMethodsClass).GetMethod(fooName, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
MethodInfo foo = fooOpen.MakeGenericMethod(new Type[] { type });

// invoke the generic (extension) method with `val` as the `this` argument:
foo.Invoke(null, new object[] { val });

关于c# - 如何调用具有结构约束的方法到未知结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27965803/

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