盒装值类型的通用拆箱

mbu*_*ics 9 .net c#

我有一个受结构限制的泛型函数.我的输入是盒装("对象").是否可以在运行时取消装箱值以避免必须检查每种可能的类型并手动执行转换?

见上面的例子:

   public struct MyStruct
    {
        public int Value;
    }

    public void Foo<T>(T test)
        where T : struct
    {
        // do stuff
    }

    public void TestFunc()
    {
        object o = new MyStruct() { Value = 100 }; // o is always a value type

        Foo(o);
    }
Run Code Online (Sandbox Code Playgroud)

在这个例子中,我知道o必须是一个结构(但是,它不需要是MyStruct ......).有没有办法在没有大量样板代码的情况下调用Foo来检查每种可能的结构类型?

谢谢.

Joh*_*lph 10

.NET Generics的实现方式允许将值类型作为泛型类型参数,而不会产生任何装箱/拆箱开销.因为你在调用Foo之前​​投射到对象你没有利用它,实际上你根本就没有利用泛型.

首先使用泛型的全部意义是替换"对象习语".我想你在这里错过了这个概念.无论T发生什么类型,它都可以在运行时使用,因为您将其约束为struct保证为struct类型.

您的TestFunc可以这样编写而没有问题:

public void TestFunc()
{
    MyStruct o = new MyStruct() { Value = 100 }; // o is always a value type

    Foo<MyStruct>(o);
}
Run Code Online (Sandbox Code Playgroud)

看看Foo,在你的例子中看起来像这样:

public void Foo<T>(T test)
    where T : struct
{
    T copy = test; // T == MyStruct
}
Run Code Online (Sandbox Code Playgroud)

编辑:

好的,因为OP澄清了他想要调用泛型方法但他不知道他的结构类型(它只是对象).使用正确的类型参数调用泛型方法的最简单方法是使用一点反射.

public void TestFunc()
{
    object o = new DateTime();

    MethodInfo method = this.GetType().GetMethod("Foo");
    MethodInfo generic = method.MakeGenericMethod(o.GetType());
    generic.Invoke(this, new object[] {o});


}
public void Foo<T>(T test)
    where T : struct
{
    T copy = test; // T == DateTime
}
Run Code Online (Sandbox Code Playgroud)