以匿名类型作为泛型参数的泛型类型实例,如何正确转换回原始类型?

温特尔

当我需要验证UT中的某些代码路径时,我遇到了这个问题。

我需要转换回其原始类型,以验证是否正确设置了数据字段。

我对类定义进行了抽象,并且在此示例中,我的UT现在位于主函数中

public interface ITestInterface { };


public class TestClass<T> : ITestInterface
{
    public T member { get; set; }
}

public static class Util
{
    public static ITestInterface Create<C>(C t)
    {
        return new TestClass<C> { member = t };
    }

    public static ITestInterface CreateInstance()
    {
        return Create(new
        {
            p1 = 100,
            p2 = "string"
        });
    }
}

class Program
{
    static void Main(string[] args)
    {

        var a = Util.CreateInstance();

        var b = a as TestClass<Object>;
        // this will be "null" in this example
        // So, how can I convert back to its real type?
        // And get the "member" data
    }
}

我认为这个例子可以准确地解释我的问题和我想要的

请更多耐心:

  1. 为什么使用匿名类型
  2. 为什么使用界面
  3. 为什么使用从非通用接口派生的模板类

我想说的是代码已经存在,我无法更改(至少当前)

我想做的是:

  1. 检查该接口是否是派生自某些类的实例 ITestInterface
  2. 如果是的话,我需要转换回该类型,可以验证其成员数据

因此,请根据这种情况分享一些解决方案/想法。

顺便提一句,

当然,我知道我在上一条语句中使用“对象”将其转换回类型不好(或者显然是错误的),但是实际上我不知道我还可以在这里放些什么。“对象”只是一种直观的尝试。请分享用于处理这种情况的任何属性方式(可能不止是用来代替“对象”的东西)。

Grax32

我并不是说这不是XY问题,而是要回答您提出的问题。

如果您与匿名类型在同一范围内,则可以将泛型使用类型推断,以将其强制转换回匿名类型。

在下面的示例中,我将在调用Util.Create之前创建匿名键入的项目,以便在变量中拥有该类型的实例,以后可以使用。然后,我调用泛型方法GetAsTestClass<T>,该方法基于第二个参数使用类型推断将T设置为匿名类型。然后返回item as TestClass<T>,其中T是您的匿名类型。

public void TestMethod1()
{
    var anonItem = new
    {
        p1 = 100,
        p2 = "string"
    };

    var a = Util.Create(anonItem);

    var b = GetAsTestClass(a, anonItem);
    // this will be "null" in this example
    // So, how can I convert back to its real type?
    // And get the "member" data

    var c = b.member;
    Assert.AreEqual(100, c.p1);

}

public TestClass<T> GetAsTestClass<T>(ITestInterface item, T silentType)
{
    return item as TestClass<T>;
}

编辑:

您的特定要求似乎排除了类型安全选项。以下是使用非类型安全反射和动态方法的代码示例。请注意,要使动态版本正常工作,您需要在项目中引用Microsoft.CSharp。

var a = Util.Create(new
{
    p1 = 100,
    p2 = "string"
});

var memberAnon = a
    .GetType()
    .GetProperty("member")
    .GetValue(a);

var p1 = memberAnon
    .GetType()
    .GetProperty("p1")
    .GetValue(memberAnon);

Assert.AreEqual(100, p1);

或动态方式

dynamic dynamicVar = a;
Assert.AreEqual(100, dynamicVar.member.p1);

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章