首页 > 解决方案 > 解析匿名类型

问题描述

我的 API 返回一个object, 填充了匿名类型。我可以GET通过 HTTP 并解析为 json。
但是...我对同一方法的单元测试无法解析匿名类型。
使用 Dotnet 框架 4.7.2。

下面的代码显示了一个项目中
的调用者和另一个项目中的被调用者,
有 2 次不同的失败尝试。第二个是从 SO和这里复制的,没有评论它不起作用。但是……不适合我。

错误信息是:

System.InvalidCastException:无法将类型“<>f__AnonymousType1`2[System.String,System.String]”的对象
转换
为类型“<>f__AnonymousType0`2[System.String,System.String]”。

可以看到类型不同的地方。
但后来 IIRC 前段时间有一个 dotnet 更新解决了这个问题,让它们“平等”。


我试图通过从 dotnet 框架 web api 返回一个匿名类型来解决一个用例。
(还有其他解决方案,如动态、反射、类型或更多端点,但这是另一个问题)
请注意,此测试用例不涉及 HTTP,它纯粹是一个 dotnet 框架问题。

WebAPI(项目 1):

public class MyController: ApiController
{
    public object Get(string id)
    {
        return new { Key = id, Value = "val:" + id };
    }
}

测试(项目 2):

[Fact]
public void MyTest
{
    var sut = new MyController();

    // Act.
    dynamic res = sut.Get("42");

    // Assert.

    // First attempt:
    Assert.Equal("42", res.Key);

    // Second attempt:
    var a = new { Key = "", Value = "" };
    a = Cast(a, res);  // <- the code fails already here

    Assert.Equal("42", a.Key);
}

private static T Cast<T>(T typeHolder, object x)
{
    // typeHolder above is just for compiler magic
    // to infer the type to cast x to
    return (T)x;
}


标签: c#anonymous-types

解决方案


转换失败是因为当您尝试强制转换匿名类型时,两个实例必须来自相同的匿名类型。即使它们具有相同类型的属性,它也不起作用,也无法执行强制转换,就像你有

public class A
{
    public string SomeProperty { get; set; }
    public string SomeOtherProperty { get; set; }
}

public class B
{
    public string SomeProperty { get; set; }
    public string SomeOtherProperty { get; set; }
}

并会尝试做类似的事情(B)instanceOfA

如果可能,您应该使用元组代替


推荐阅读