当我需要在我的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
}
}
我认为这个例子可以解释我的问题以及我想要的内容
请耐心等待:
我想说代码已经存在,我无法改变它(至少目前)
我想做的是:
ITestInterface
所以请根据这种情况分享一些解决方案/想法。
顺便说一句,
当然我知道我正在使用&#34; Object&#34;在我的最后一个声明转换回类型是不好(或明显错误),但实际上我不知道我可以在这里放哪些其他东西。 &#34;对象&#34;只是一个直观的尝试。请分享任何财产方式来处理这种情况(可能不仅仅是用来取代&#34;对象&#34;)。
答案 0 :(得分:0)
我不是说这不是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);