diff --git a/csharp/src/Google.Protobuf/Reflection/ReflectionUtil.cs b/csharp/src/Google.Protobuf/Reflection/ReflectionUtil.cs index 1afaa90c9..80d5c774f 100644 --- a/csharp/src/Google.Protobuf/Reflection/ReflectionUtil.cs +++ b/csharp/src/Google.Protobuf/Reflection/ReflectionUtil.cs @@ -163,6 +163,8 @@ namespace Google.Protobuf.Reflection { try { + PreventLinkerFailures(); + // Try to do the conversion using reflection, so we can see whether it's supported. MethodInfo method = typeof(ReflectionUtil).GetMethod(nameof(SampleEnumMethod)); // If this passes, we're in a reasonable runtime. method.CreateDelegate(typeof(Func)); @@ -174,6 +176,23 @@ namespace Google.Protobuf.Reflection } } + /// + /// This method is effectively pointless, but only called once. It's present (and called) + /// to avoid the Unity linker from removing code that's only called via reflection. + /// + private static void PreventLinkerFailures() + { + // Exercise the method directly. This should avoid any pro-active linkers from stripping + // the method out. + SampleEnum x = SampleEnumMethod(); + if (x != SampleEnum.X) + { + throw new InvalidOperationException("Failure in reflection utilities"); + } + // Make sure the ReflectionHelper parameterless constructor isn't removed... + var helper = new ReflectionHelper(); + } + public enum SampleEnum { X