我无法将一个匿名类型转换为另一个。我想知道为什么。
public static class Class1{
public static object GetFinance(Guid contractB2CId)
{
return new
{
Item1 = reader.ValueOrDefault<decimal>(0),
Item2 = reader.ValueOrDefault<decimal>(1),
Item3 = reader.ValueOrDefault<decimal>(2),
Item4 = reader.ValueOrDefault<decimal>(3),
Item5 = reader.ValueOrDefault<decimal>(4),
Item6 = reader.ValueOrDefault<decimal>(5)
};
}
object obj = GetFinance();
var financeInfo = obj.UnsafeCast(new
{
Item1 = default(decimal),
Item2 = default(decimal),
Item3 = default(decimal),
Item4 = default(decimal),
Item5 = default(decimal),
Item6 = default(decimal)
});
}
public static class Class2{
public static T UnsafeCast<T>(this object obj, T type)
{
return (T) obj;
}
}
例外
无法投射类型的对象 。 '&LT;&GT; f__AnonymousType1
6[System.Decimal,System.Decimal,System.Decimal,System.Decimal,System.Decimal,System.Decimal]' to type '<>f__AnonymousType0
6 [System.Decimal,System.Decimal,System.Decimal,System.Decimal,System.Decimal,System.Decimal]'
更新:
有没有办法避免这种异常,除了使用Tuple<decimal.....>
或使用一个程序集?
答案 0 :(得分:7)
匿名类型绑定到声明它们的程序集(技术上,模块)。我的猜测是这个代码在不同的程序集中。因此,它们完全不同,看起来很相似。
请注意,动态生成的代码(ASP.NET页面等)将位于不同的程序集中。
顺便说一句,这个技巧被称为“逐个演员”,只要类型在同一个程序集中,它就可以正常工作(只是测试它)。
这里有效,因为它都在一个程序集中:
static class Program
{
static void Main()
{
object obj = GetFinance();
var financeInfo = obj.UnsafeCast(new
{
Item1 = default(decimal), Item2 = default(decimal),
Item3 = default(decimal), Item4 = default(decimal),
Item5 = default(decimal), Item6 = default(decimal)
});
System.Console.WriteLine(financeInfo.Item3); // 76
}
public static object GetFinance()
{
decimal x = 76;
return new
{
Item1 = x, Item2 = x, Item3 = x,
Item4 = x, Item5 = x, Item6 = x
};
}
public static T UnsafeCast<T>(this object obj, T type)
{
return (T)obj;
}
}
答案 1 :(得分:2)
从错误消息中可以看出,编译器生成了2种不同的类型。 f__AnonymousType1
和f__AnonymousType0
。而且他们没有任何关系。
它们包含(完全)相同属性的事实是巧合,编译器不会在两个“相同”类型之间进行转换。他们必须有关系。
没有匿名类型的同样问题:
class A1
{
public int Id { get; set; }
}
class A2
{
public int Id { get; set; }
}
A1 a = new A1();
A2 b = (A2) a; // error
错误1无法将“MyApp.A1”类型转换为“MyApp.A2”
但如果您使用的是C#4,请查看Tuple<T1,T2,T3,T4,T5,T6>
。它应该让你做同样的事情或至少类似的东西。
答案 2 :(得分:1)
如果你看一下例外,你会发现它们是两种不同的类型。一个不是来自另一个。
规格说明:
An anonymous type is a nameless class type that inherits directly from object An anonymous type is a nameless class type that inherits directly from object. The members of an anonymous type are a sequence of read/write properties inferred from the object initializer(s) used to create instances of the type. Specifically. Within the same program, two anonymous object initializers that specify a sequence of properties of the same names and types in the same order will produce instances of the same anonymous type
从错误消息中获取您必须从对象派生的不同类型。那么为什么你希望能够从一个投射到另一个呢?
如果你有
class foo<T1,T2,T3,T4,T5,T6>{
T1 Item1
T2 Item2
T3 Item3
T4 Item4
T5 Item5
T6 Item6
}
和
class Bar<T1,T2,T3,T4,T5,T6>{
T1 Item1
T2 Item2
T3 Item3
T4 Item4
T5 Item5
T6 Item6
}
你还希望能够在这两者之间施展吗?
唯一的区别是类型的名称。我的名字叫做Foo和Bar你的&lt;&gt; f_ AnonymousType1和&lt;&gt; f _AnonymousType0
答案 3 :(得分:0)
这些在技术上是2个完全独立的类。你不能只在两个类之间进行投射,因为它们看起来像是彼此。对于该语言,尝试将双精度转换为按钮同样是不可能的。 如果您使用c#4.0,我建议使用通用的Tuple类,使所有内容都输入。 如果没有,请编写自己的小班以供使用。