我有一些代码使用匿名类型的反射来将数据填充到URI模式中,如下所示:
var uri = UriUtility.FromPattern("/{action}/{id}.{contentType}", new {
action = "foo",
id = 1234,
contentType = "xml"
});
当我使用MonoTouch选项"链接所有程序集"时,匿名类型成员被剥离,我的代码在运行时失败。有没有办法告诉MonoTouch链接器保留匿名类型的所有成员?
更新
这是一个完整的测试案例,展示了这个问题。测试仅在链接SDK程序集时传递,并且在链接所有程序集时失败。
using System;
using System.Collections.Generic;
using System.Reflection;
using MonoTouch.Foundation;
using NUnit.Framework;
namespace LinkerTests.iOS
{
[Preserve(AllMembers = true)]
[TestFixture]
public class AnonymousTypeTests
{
[Test]
public void Test()
{
var str = string.Join(",", AnonymousTypeUtil.GetProperties(new { a = "a", b = "b" }));
Assert.AreEqual("a=a,b=b", str);
}
}
internal static class AnonymousTypeUtil
{
public static IEnumerable<string> GetProperties(object o)
{
foreach (var property in o.GetType().GetRuntimeProperties())
{
object value = property.GetValue(o);
yield return property.Name + "=" + value;
}
}
}
}
答案 0 :(得分:2)
我收到了Xamarin的确认,目前无法做到这一点。
答案 1 :(得分:0)
我不确定它是一个链接器问题,即三个字段是分配/使用的,并且不会被链接器删除)至少它不是匿名类型的问题。
启用链接器(全部链接)这是我在Xamarin Studio(即时窗口)中看到的内容:
> ? o
{{ action = foo, id = 1234, contentType = xml }}
然而,正如@Servy所提到的那样,那些字段是而不是 public(而且是编译器,而不是这样做的链接器)。您需要在反映代码中将它们作为非公共字段进行访问,例如
> o.GetType ().GetField ("<action>", BindingFlags.Instance | BindingFlags.NonPublic)
{System.String <action>}
Attributes: System.Reflection.FieldAttributes.InitOnly|System.Reflection.FieldAttributes.Private
DeclaringType: {<>__AnonType0`3[System.String,System.Int32,System.String]}
FieldHandle: {System.RuntimeFieldHandle}
FieldType: {System.String}
IsInitOnly: true
IsLiteral: false
IsNotSerialized: false
IsPrivate: true
IsStatic: false
MemberType: 4
MetadataToken: 67108914
Name: "<action>"
ReflectedType: {<>__AnonType0`3[System.String,System.Int32,System.String]}
Non-public members:
如果不知道UriUtility.FromPattern
使用反射做什么(以及如何),我无法进一步诊断。您可能希望更新您的问题和/或提交bug report并提供完整的测试用例。
OTOH我确定这个示例应该与链接器和反射一起正常工作(但是在启用链接器时使用反射仍然很棘手,因为静态分析无法准确地确定什么&#39;被使用)。