1

首先,一般注意,Xamarin 所谓的“链接器”实际上更像是“死代码删除器”。它应该防止不可调用的代码进入已编译的应用程序。

我的应用程序中有一个类型。当我使用反射来获取它的构造函数时,我看到零构造函数:

private static int GetConstructorCount(Type type) {
  ConstructorInfo[] constructors = type.GetConstructors();
  return constructors.Count();
}

然而,当我使用反射查看它的实例成员时,我看到了很多:

private static void LogMemberInfo(Type type) {
  int constructorCount = GetConstructorCount(type);
  MyLoggingMethod(constructorCount, "Constructors");
  MemberInfo[] members = type.GetMembers();
  List<string> willLog = new List<string>();
  foreach(MemberInfo member in members) {
    if (member.DeclaringType == type) {
      willLog.Add(member.Name);
    } 
  }
  willLog.Sort();
  foreach (string str in willLog) {
    MyLoggingMethod.LogLine(str);
  }
}

上面的输出是:

0 Constructors
lots of surviving members, including instance members

这是一个问题,因为该类型是通往许多其他类型的门户。我希望通过摆脱所有构造函数,所有实例成员都会消失。他们没有。

这是链接器中的错误吗?或者它是否仍然不想摆脱实例成员?

我确实通过强制转换访问该类型的成员。也许这就是问题所在?

public class MySuperclass {
   public static MySuperclass Instance {get; set;}
}

public MyClass: MySuperclass {
  public static SomeMethod() {
     MySuperclass object = MySuperclass.Instance;
     MyClass castObject = object as MyClass; // castObject will always be null, as no constructors survived the linking process. But maybe the linker doesn't realize that?
     if (castObject!=null) {
        castObject.InstanceMethod();
     }
  }
}

更新:摆脱所有演员并没有解决问题。我在很多地方都在调用超类对象的虚拟成员;这是我的下一个猜测,但如果这是问题所在,修复将是一团糟。

4

2 回答 2

0

至少在我的情况下,对类型调用任何静态方法都会导致保留大量实例成员。我真的试过这个:

public class MyType() {
  public static bool DummyBool() {
    return true;
  }
  // instance members here
}

一旦类型被链接器删除,我就调用了 MyType.DummyBool()。这导致许多实例成员被保留。

这可能不是每个人的情况。但对我来说就是这样。

另一个需要注意的阴险的事情是,如果静态类具有在启动时初始化的任何属性,并且整个类被保留,那么这些属性将被保留,即使它们从未被调用:

public static class StaticClass {
  public static Foo FooProperty {get;} = new Foo(); // if any code that is not removed calls StaticClass.SomeString, then Foo will be preserved.
  public static string SomeString {
    get {
      return "Hello";
    }
  }
}

我还看到至少一种情况,即链接器删除的类中的代码仍然导致另一个类不被删除。我认为这是一个错误;但是,我的示例相当复杂,并且我尝试进行简单复制的尝试失败了。

于 2017-02-16T06:55:42.250 回答
0

您是否尝试过使用 Preserve 属性?链接器不会“优化”用它装饰的代码:

[Xamarin.iOS.Foundation.Preserve]

有关详细信息,请参阅此处的 Xamarin 文档

于 2017-02-16T15:47:39.530 回答