繁体   English   中英

如何使用没有约束的类型参数调用具有泛型约束的方法?

[英]How to call a method with a generic constraint using a type parameter without the constraint?

假设我有一个方法:

public void ExampleMethod<T>(T x) where T : struct // or new()
{
    // example usage, similar to what's actually happening
    var z = (T)Enum.Parse(typeof(T), privateFieldOfTypeString);

    // do something depending on values of x and z
    // possibly using other methods that require them being enums

    // or in case of the new() constraint:
    // var t = new T() and do something together with x
}

我想用它如下:

public void CallerMethod<S>(S y)
{
    if (typeof(S).IsEnum) // or some other invariant meaning that `S` is "new()able"
    {
        ExampleMethod(y); // won't compile
    }
}

因此,在运行期间我知道S满足ExampleMethod<T>的约束。 我知道可以使用反射调用它,类似于:

this
    .GetType()
    .GetMethod(nameof(ExampleMethod<object>))
    .MakeGenericMethod(typeof(S))
    .Invoke(this, new object[] { y });

没有反思可能吗?

注意:这是来自现实生活示例的简化代码,显然我无法控制这些方法的签名,因此答案“将约束添加到CallerMethod ”和“从ExampleMethod删除约束”无效。

是的,整个事情应该重新设计,所以整个问题根本不会出现。 但正如在现实生活中一样,“整个事情”太大,太耦合,风险太大而无法重写。 一些要求以一种意想不到的方式发生了变化 - 因此明显的代码气味,我试图通过将其隐藏在一个看起来很讨厌的地方来最小化。

你可以使用dynamic

if (typeof(S).IsEnum)
{
    ExampleMethod((dynamic)y);
}

您可以利用运算符重载; 定义CallerMethod多个显式版本, CallerMethod版本都可以成功地对ExampleMethod进行后续调用

CallerMethod(Enum1 value) { ExampleMethod(value); }
CallerMethod(Enum2 value) { ExampleMethod(value); }
CallerMethod(Enum3 value) { ExampleMethod(value); }

等等

如果有大量的成长型需要一个版本的CallerMethod你可以写一个T4模板来生成partial与所有的实现类。

如果枚举类型是已知的,一种可能性,虽然详细,但将转换为已知类型。

例如,作为一个起点,

public void CallerMethod<S>(S y) {
    if (typeof(S).IsEnum) {
        if (y is KnownEnum) {
            var z = (KnownEnum)Enum.Parse(typeof(S), y.ToString());
            ExampleMethod(z);
        }
        if (y is KnownEnum2) {
            var z = (KnownEnum2)Enum.Parse(typeof(S), y.ToString());
            ExampleMethod(z);
        }
        //...
    }
}

在您的特定情况下,您可以转换为int。

public void CallerMethod<S>(S y)
{
    if (typeof(S).IsEnum)
    {
        ExampleMethod((int)y);
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM