首页 > 解决方案 > 在 C# 中结合动态绑定和非托管约束

问题描述

前提:

让我们看下面的代码示例:

using System;

public class Program
{
    public static unsafe void f(StringComparison c)
    {
        // One overload used to pin the handle to the memory on the GC Heap and do unsafe stuff.
        // Can be generic as well, but I chose to simplify the example for better clarity.
    }

    public static void f(string c)
    {
        // Another overload just to describe the problem.
    }

    public static void Main()
    {
        // Returns an instance of StringComparison at runtime with the compile-time type of object.
        dynamic c = Activator.CreateInstance(typeof(StringComparison));

        // Resolves to f(StringComparison) and everything works as expected.
        f(c);
    }
}

这里正确的重载是通过绑定f成功调用的。dynamic


当我将unmanaged约束添加到与泛型的混合中时,如下所示(MCVE):

using System;

public class Program
{
    public static unsafe void f<T>(T v) where T : unmanaged
    {
        // Unsafe generic method needed to handle primitive types and enums (including user defined ones).
        // Unsafe because of the same reason in the first sample.
    }

    public static void f(string s)
    {
        // Another overload just to describe the problem.
    }


    public static void Main()
    {
        // Returns an instance of StringComparison at runtime with the compile-time type of object.
        dynamic c = Activator.CreateInstance(typeof(StringComparison));

        // Oops! We have an error!
        // error CS8377: The type 'dynamic' must be a non-nullable value type,
        // along with all fields at any level of nesting,
        // in order to use it as parameter 'T' in the generic type or method 'Program.f<T>(T)'
        f(c);
    }
}

笔记:

  1. 过载f(string)仅用于说明问题。任何强制f<T>(T)选择重载的不兼容类型也可以工作。
  2. Activator.CreateInstance还用于说明在运行时返回正确类型(enum在本例中为 an)实例的函数。

我不熟悉dynamic在运行时执行重载解析的机制,但MSDN建议:

dynamic假定支持任何操作。

由于第一个示例有效(dynamic能够绑定到一个enum,满足未明确指定的约束unmanaged),我希望第二个示例也可以工作。

问题:

  1. 这种行为是预期的还是错误?如果是预期的,请解释原因。
  2. f<T>(T)是否有任何解决方法可以在不使用反射的情况下调用泛型重载?

标签: c#dynamicconstraintsunsafeoverload-resolution

解决方案


推荐阅读