|
@@ -50,6 +50,29 @@ namespace Google.Protobuf.Reflection
|
|
/// </summary>
|
|
/// </summary>
|
|
internal static class ReflectionUtil
|
|
internal static class ReflectionUtil
|
|
{
|
|
{
|
|
|
|
+ static ReflectionUtil()
|
|
|
|
+ {
|
|
|
|
+ ForceInitialize<string>(); // Handles all reference types
|
|
|
|
+ ForceInitialize<int>();
|
|
|
|
+ ForceInitialize<long>();
|
|
|
|
+ ForceInitialize<uint>();
|
|
|
|
+ ForceInitialize<ulong>();
|
|
|
|
+ ForceInitialize<float>();
|
|
|
|
+ ForceInitialize<double>();
|
|
|
|
+ ForceInitialize<bool>();
|
|
|
|
+ ForceInitialize<int?>();
|
|
|
|
+ ForceInitialize<long?>();
|
|
|
|
+ ForceInitialize<uint?>();
|
|
|
|
+ ForceInitialize<ulong?>();
|
|
|
|
+ ForceInitialize<float?>();
|
|
|
|
+ ForceInitialize<double?>();
|
|
|
|
+ ForceInitialize<bool?>();
|
|
|
|
+ ForceInitialize<SampleEnum>();
|
|
|
|
+ SampleEnumMethod();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ internal static void ForceInitialize<T>() => new ReflectionHelper<IMessage, T>();
|
|
|
|
+
|
|
/// <summary>
|
|
/// <summary>
|
|
/// Empty Type[] used when calling GetProperty to force property instead of indexer fetching.
|
|
/// Empty Type[] used when calling GetProperty to force property instead of indexer fetching.
|
|
/// </summary>
|
|
/// </summary>
|
|
@@ -163,7 +186,6 @@ namespace Google.Protobuf.Reflection
|
|
{
|
|
{
|
|
try
|
|
try
|
|
{
|
|
{
|
|
- PreventLinkerFailures();
|
|
|
|
// Try to do the conversion using reflection, so we can see whether it's supported.
|
|
// Try to do the conversion using reflection, so we can see whether it's supported.
|
|
MethodInfo method = typeof(ReflectionUtil).GetMethod(nameof(SampleEnumMethod));
|
|
MethodInfo method = typeof(ReflectionUtil).GetMethod(nameof(SampleEnumMethod));
|
|
// If this passes, we're in a reasonable runtime.
|
|
// If this passes, we're in a reasonable runtime.
|
|
@@ -176,23 +198,6 @@ namespace Google.Protobuf.Reflection
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- /// <summary>
|
|
|
|
- /// 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.
|
|
|
|
- /// </summary>
|
|
|
|
- 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<int, int>();
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
public enum SampleEnum
|
|
public enum SampleEnum
|
|
{
|
|
{
|
|
X
|
|
X
|