首先,一般说明,Xamarin称他们的"链接器"实际上更像是一个“死代码移除器”#34;它应该防止不可调用的代码进入已编译的应用程序。
我的应用中有一个类型。当我使用反射来获取它的构造函数时,我看到零构造函数:
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();
}
}
}
更新:摆脱所有演员阵容并没有解决问题。我在很多地方调用超类对象的虚拟成员;这是我的下一个猜测,但如果这是问题,那么修复将会很混乱。
答案 0 :(得分: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";
}
}
}
我还看到至少一种情况,即链接器删除的类中的代码仍会导致另一个类不被删除。我认为这是一个错误;然而,我的例子相当复杂,我试图获得一个简单的复制失败了。
答案 1 :(得分:0)