* Consolidate .netcoreapp.cs files because System.Reflection project is no longer cross-compiled
* Move extensions to separate class
[assembly: CompilationRelaxations(8)]
[assembly: Debuggable((DebuggableAttribute.DebuggingModes)263)]
[assembly: CLSCompliant(false)]
+[assembly: TypeForwardedTo(typeof(string))]
+[assembly: TypeForwardedTo(typeof(TypeInForwardedAssembly))]
namespace System.Reflection.Tests
{
}
[Fact]
- public void SecurityRuleSet_Netcore()
+ public void SecurityRuleSetTest()
{
Assert.Equal(SecurityRuleSet.None, typeof(AssemblyTests).Assembly.SecurityRuleSet);
}
var loadedAssembly1 = Assembly.LoadFile(fullRuntimeTestsPath);
Assert.NotEqual(currentAssembly, loadedAssembly1);
-#if NETCOREAPP
System.Runtime.Loader.AssemblyLoadContext alc = System.Runtime.Loader.AssemblyLoadContext.GetLoadContext(loadedAssembly1);
string expectedName = string.Format("Assembly.LoadFile({0})", fullRuntimeTestsPath);
Assert.Equal(expectedName, alc.Name);
Assert.Contains(fullRuntimeTestsPath, alc.Name);
Assert.Contains(expectedName, alc.ToString());
Assert.Contains("System.Runtime.Loader.IndividualAssemblyLoadContext", alc.ToString());
-#endif
string dir = Path.GetDirectoryName(fullRuntimeTestsPath);
fullRuntimeTestsPath = Path.Combine(dir, ".", RuntimeTestsDll);
}
[Fact]
- public void LoadFile_NullPath_Netcore_ThrowsArgumentNullException()
+ public void LoadFile_NullPath_ThrowsArgumentNullException()
{
AssertExtensions.Throws<ArgumentNullException>("path", () => Assembly.LoadFile(null));
}
}
[Fact]
- public void LoadFromUsingHashValue_Netcore()
+ public void LoadFromUsingHashValue()
{
Assert.Throws<NotSupportedException>(() => Assembly.LoadFrom("abc", null, System.Configuration.Assemblies.AssemblyHashAlgorithm.SHA1));
}
}
[Fact]
- public void LoadFrom_WithHashValue_NetCoreCore_ThrowsNotSupportedException()
+ public void LoadFrom_WithHashValue_ThrowsNotSupportedException()
{
Assert.Throws<NotSupportedException>(() => Assembly.LoadFrom(DestTestAssemblyPath, new byte[0], Configuration.Assemblies.AssemblyHashAlgorithm.None));
}
[Fact]
- public void LoadModule_Netcore()
+ public void LoadModule()
{
Assembly assembly = typeof(AssemblyTests).Assembly;
Assert.Throws<NotImplementedException>(() => assembly.LoadModule("abc", null));
Assert.True(customAttributesData.Count() > 0, $"Did not find custom attribute of type {attrType}");
}
+ [Fact]
+ public static void AssemblyGetForwardedTypes()
+ {
+ Assembly a = typeof(AssemblyTests).Assembly;
+ Type[] forwardedTypes = a.GetForwardedTypes();
+
+ forwardedTypes = forwardedTypes.OrderBy(t => t.FullName).ToArray();
+
+ Type[] expected = { typeof(string), typeof(TypeInForwardedAssembly), typeof(TypeInForwardedAssembly.PublicInner), typeof(TypeInForwardedAssembly.PublicInner.PublicInnerInner) };
+ expected = expected.OrderBy(t => t.FullName).ToArray();
+
+ Assert.Equal<Type>(expected, forwardedTypes);
+ }
+
+ [Fact]
+ public static void AssemblyGetForwardedTypesLoadFailure()
+ {
+ Assembly a = typeof(TypeInForwardedAssembly).Assembly;
+ ReflectionTypeLoadException rle = Assert.Throws<ReflectionTypeLoadException>(() => a.GetForwardedTypes());
+ Assert.Equal(2, rle.Types.Length);
+ Assert.Equal(2, rle.LoaderExceptions.Length);
+
+ bool foundSystemObject = false;
+ bool foundBifException = false;
+ for (int i = 0; i < rle.Types.Length; i++)
+ {
+ Type type = rle.Types[i];
+ Exception exception = rle.LoaderExceptions[i];
+
+ if (type == typeof(object) && exception == null)
+ foundSystemObject = true;
+
+ if (type == null && exception is BadImageFormatException)
+ foundBifException = true;
+ }
+
+ Assert.True(foundSystemObject);
+ Assert.True(foundBifException);
+ }
+
private static Assembly LoadSystemCollectionsAssembly()
{
// Force System.collections to be linked statically
+++ /dev/null
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using System.Reflection;
-using System.Runtime.CompilerServices;
-using Xunit;
-
-[assembly:TypeForwardedTo(typeof(string))]
-[assembly: TypeForwardedTo(typeof(TypeInForwardedAssembly))]
-
-namespace System.Reflection.Tests
-{
- public static class AssemblyNetCoreAppTests
- {
- [Fact]
- public static void AssemblyGetForwardedTypes()
- {
- Assembly a = typeof(AssemblyNetCoreAppTests).Assembly;
- Type[] forwardedTypes = a.GetForwardedTypes();
-
- forwardedTypes = forwardedTypes.OrderBy(t => t.FullName).ToArray();
-
- Type[] expected = { typeof(string), typeof(TypeInForwardedAssembly), typeof(TypeInForwardedAssembly.PublicInner), typeof(TypeInForwardedAssembly.PublicInner.PublicInnerInner) };
- expected = expected.OrderBy(t => t.FullName).ToArray();
-
- Assert.Equal<Type>(expected, forwardedTypes);
- }
-
- [Fact]
- public static void AssemblyGetForwardedTypesLoadFailure()
- {
- Assembly a = typeof(TypeInForwardedAssembly).Assembly;
- ReflectionTypeLoadException rle = Assert.Throws<ReflectionTypeLoadException>(() => a.GetForwardedTypes());
- Assert.Equal(2, rle.Types.Length);
- Assert.Equal(2, rle.LoaderExceptions.Length);
-
- bool foundSystemObject = false;
- bool foundBifException = false;
- for (int i = 0; i < rle.Types.Length; i++)
- {
- Type type = rle.Types[i];
- Exception exception = rle.LoaderExceptions[i];
-
- if (type == typeof(object) && exception == null)
- foundSystemObject = true;
-
- if (type == null && exception is BadImageFormatException)
- foundBifException = true;
- }
-
- Assert.True(foundSystemObject);
- Assert.True(foundBifException);
- }
- }
-}
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+using System.Diagnostics;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Xunit;
#pragma warning disable 0414
+#pragma warning disable 0649 // Yes, we know - test class have fields we don't assign to.
namespace System.Reflection.Tests
{
}
}
+ [Fact]
+ public static void HasSameMetadataDefinitionAs_GenericClassMembers()
+ {
+ Type tGeneric = typeof(GenericTestClass<>);
+ IEnumerable<MethodInfo> methodsOnGeneric = tGeneric.GetTypeInfo().GetDeclaredMethods(nameof(GenericTestClass<object>.Foo));
+
+ List<Type> typeInsts = new List<Type>();
+ foreach (MethodInfo method in methodsOnGeneric)
+ {
+ Debug.Assert(method.GetParameters().Length == 1);
+ Type parameterType = method.GetParameters()[0].ParameterType;
+ typeInsts.Add(tGeneric.MakeGenericType(parameterType));
+ }
+ typeInsts.Add(tGeneric);
+ CrossTestHasSameMethodDefinitionAs(typeInsts.ToArray());
+ }
+
+ private static void CrossTestHasSameMethodDefinitionAs(params Type[] types)
+ {
+ Assert.All(types,
+ delegate (Type type1)
+ {
+ Assert.All(type1.GenerateTestMemberList(),
+ delegate (MemberInfo m1)
+ {
+ MarkerAttribute mark1 = m1.GetCustomAttribute<MarkerAttribute>();
+ if (mark1 == null)
+ return;
+
+ Assert.All(types,
+ delegate (Type type2)
+ {
+ Assert.All(type2.GenerateTestMemberList(),
+ delegate (MemberInfo m2)
+ {
+ MarkerAttribute mark2 = m2.GetCustomAttribute<MarkerAttribute>();
+ if (mark2 == null)
+ return;
+
+ bool hasSameMetadata = m1.HasSameMetadataDefinitionAs(m2);
+ Assert.Equal(hasSameMetadata, m2.HasSameMetadataDefinitionAs(m1));
+
+ if (hasSameMetadata)
+ {
+ Assert.Equal(mark1.Mark, mark2.Mark);
+ }
+ else
+ {
+ Assert.NotEqual(mark1.Mark, mark2.Mark);
+ }
+ }
+ );
+ }
+ );
+ }
+ );
+ }
+ );
+ }
+
+ [Fact]
+ public static void HasSameMetadataDefinitionAs_ReflectedTypeNotPartOfComparison()
+ {
+ Type tBase = typeof(GenericTestClass<>);
+ Type tDerived = typeof(DerivedFromGenericTestClass<int>);
+ BindingFlags bf = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance;
+
+ IEnumerable<MemberInfo> baseMembers = tBase.GetMembers(bf).Where(m => m.IsDefined(typeof(MarkerAttribute)));
+ baseMembers = baseMembers.Where(bm => !(bm is ConstructorInfo)); // Constructors cannot be seen from derived types.
+ IEnumerable<MemberInfo> derivedMembers = tDerived.GetMembers(bf).Where(m => m.IsDefined(typeof(MarkerAttribute)));
+ Assert.All(baseMembers,
+ delegate (MemberInfo baseMember)
+ {
+ MemberInfo matchingDerivedMember = derivedMembers.Single(dm => dm.HasSameMarkAs(baseMember));
+ Assert.True(baseMember.HasSameMetadataDefinitionAs(matchingDerivedMember));
+ Assert.True(matchingDerivedMember.HasSameMetadataDefinitionAs(matchingDerivedMember));
+ }
+ );
+ }
+
+ [Fact]
+ public static void HasSameMetadataDefinitionAs_ConstructedGenericMethods()
+ {
+ Type t1 = typeof(TestClassWithGenericMethod<>);
+ Type theT = t1.GetTypeInfo().GenericTypeParameters[0];
+
+ MethodInfo mooNormal = t1.GetConfirmedMethod(nameof(TestClassWithGenericMethod<object>.Moo), theT);
+ MethodInfo mooGeneric = t1.GetTypeInfo().GetDeclaredMethods("Moo").Single(m => m.IsGenericMethod);
+
+ MethodInfo mooInst = mooGeneric.MakeGenericMethod(typeof(int));
+ Assert.True(mooGeneric.HasSameMetadataDefinitionAs(mooInst));
+ Assert.True(mooInst.HasSameMetadataDefinitionAs(mooGeneric));
+
+ MethodInfo mooInst2 = mooGeneric.MakeGenericMethod(typeof(double));
+ Assert.True(mooInst2.HasSameMetadataDefinitionAs(mooInst));
+ Assert.True(mooInst.HasSameMetadataDefinitionAs(mooInst2));
+
+ Type t2 = typeof(TestClassWithGenericMethod<int>);
+ MethodInfo mooNormalOnT2 = t2.GetConfirmedMethod(nameof(TestClassWithGenericMethod<object>.Moo), typeof(int));
+ Assert.False(mooInst.HasSameMetadataDefinitionAs(mooNormalOnT2));
+ }
+
+ [Fact]
+ public static void HasSameMetadataDefinitionAs_NamedAndGenericTypes()
+ {
+ Type tnong = typeof(TestClass);
+ Type tnong2 = typeof(TestClass2);
+ Type tg = typeof(GenericTestClass<>);
+ Type tginst1 = typeof(GenericTestClass<int>);
+ Type tginst2 = typeof(GenericTestClass<string>);
+
+
+ Assert.True(tnong.HasSameMetadataDefinitionAs(tnong));
+ Assert.True(tnong2.HasSameMetadataDefinitionAs(tnong2));
+ Assert.True(tg.HasSameMetadataDefinitionAs(tg));
+ Assert.True(tginst1.HasSameMetadataDefinitionAs(tginst1));
+ Assert.True(tginst2.HasSameMetadataDefinitionAs(tginst2));
+
+ Assert.True(tg.HasSameMetadataDefinitionAs(tginst1));
+ Assert.True(tginst1.HasSameMetadataDefinitionAs(tginst1));
+ Assert.True(tginst1.HasSameMetadataDefinitionAs(tginst2));
+
+ Assert.False(tnong.HasSameMetadataDefinitionAs(tnong2));
+ Assert.False(tnong.HasSameMetadataDefinitionAs(tg));
+ Assert.False(tg.HasSameMetadataDefinitionAs(tnong));
+ Assert.False(tnong.HasSameMetadataDefinitionAs(tginst1));
+ Assert.False(tginst1.HasSameMetadataDefinitionAs(tnong));
+ }
+
+ [Fact]
+ public static void HasSameMetadataDefinitionAs_GenericTypeParameters()
+ {
+ Type theT = typeof(GenericTestClass<>).GetTypeInfo().GenericTypeParameters[0];
+ Type theT2 = typeof(TestClassWithGenericMethod<>).GetTypeInfo().GenericTypeParameters[0];
+
+ BindingFlags bf = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance | BindingFlags.DeclaredOnly | BindingFlags.ExactBinding;
+ MethodInfo mooNong = theT2.GetMethod("Moo", bf, null, new Type[] { theT2 }, null);
+ MethodInfo mooGeneric = typeof(TestClassWithGenericMethod<>).GetTypeInfo().GetDeclaredMethods("Moo").Single(m => m.IsGenericMethod);
+ Type theM = mooGeneric.GetGenericArguments()[0];
+
+ Assert.True(theT.HasSameMetadataDefinitionAs(theT));
+ Assert.False(theT2.HasSameMetadataDefinitionAs(theT));
+ Assert.False(theT.HasSameMetadataDefinitionAs(theT2));
+ Assert.False(theM.HasSameMetadataDefinitionAs(theT));
+ Assert.False(theM.HasSameMetadataDefinitionAs(theT2));
+ Assert.False(theT2.HasSameMetadataDefinitionAs(theM));
+ Assert.False(theT.HasSameMetadataDefinitionAs(theM));
+ }
+
+ [Fact]
+ public static void HasSameMetadataDefinitionAs_Twins()
+ {
+ // This situation is particularly treacherous for CoreRT as the .NET Native toolchain can and does assign
+ // the same native metadata tokens to identically structured members in unrelated types.
+ Type twin1 = typeof(Twin1);
+ Type twin2 = typeof(Twin2);
+
+ Assert.All(twin1.GenerateTestMemberList(),
+ delegate (MemberInfo m1)
+ {
+ Assert.All(twin2.GenerateTestMemberList(),
+ delegate (MemberInfo m2)
+ {
+ Assert.False(m1.HasSameMetadataDefinitionAs(m2));
+ }
+ );
+ }
+ );
+ }
+
+ private class Twin1
+ {
+ public Twin1() { }
+ public int Field1;
+ public Action Event1;
+ public void Method1() { }
+ public int Property1 { get; set; }
+ }
+
+ private class Twin2
+ {
+ public Twin2() { }
+ public int Field1;
+ public Action Event1;
+ public void Method1() { }
+ public int Property1 { get; set; }
+ }
+
+ [Fact]
+ [OuterLoop] // Time-consuming.
+ public static void HasSameMetadataDefinitionAs_CrossAssembly()
+ {
+ // Make sure that identical tokens in different assemblies don't confuse the api.
+ foreach (Type t1 in typeof(object).Assembly.DefinedTypes)
+ {
+ foreach (Type t2 in typeof(MemberInfoTests).Assembly.DefinedTypes)
+ {
+ Assert.False(t1.HasSameMetadataDefinitionAs(t2));
+ }
+ }
+ }
+
+ [Theory]
+ [MemberData(nameof(NegativeTypeData))]
+ public static void HasSameMetadataDefinitionAs_Negative_NonRuntimeType(Type type)
+ {
+ Type mockType = new MockType();
+ Assert.False(type.HasSameMetadataDefinitionAs(mockType));
+ Assert.All(type.GenerateTestMemberList(),
+ delegate (MemberInfo member)
+ {
+ Assert.False(member.HasSameMetadataDefinitionAs(mockType));
+ }
+ );
+ }
+
+ [Theory]
+ [MemberData(nameof(NegativeTypeData))]
+ public static void HasSameMetadataDefinitionAs_Negative_Null(Type type)
+ {
+ AssertExtensions.Throws<ArgumentNullException>("other", () => type.HasSameMetadataDefinitionAs(null));
+ Assert.All(type.GenerateTestMemberList(),
+ delegate (MemberInfo member)
+ {
+ AssertExtensions.Throws<ArgumentNullException>("other", () => member.HasSameMetadataDefinitionAs(null));
+ }
+ );
+ }
+
+ public static IEnumerable<object[]> NegativeTypeData => NegativeTypeDataRaw.Select(t => new object[] { t });
+ private static IEnumerable<Type> NegativeTypeDataRaw
+ {
+ get
+ {
+ yield return typeof(TestClass);
+ yield return typeof(GenericTestClass<>);
+ yield return typeof(GenericTestClass<int>);
+
+ yield return typeof(int[]);
+ yield return typeof(int).MakeArrayType(1);
+ yield return typeof(int[,]);
+ yield return typeof(int).MakeByRefType();
+ yield return typeof(int).MakePointerType();
+
+ yield return typeof(GenericTestClass<>).GetTypeInfo().GenericTypeParameters[0];
+ if (PlatformDetection.IsWindows)
+ yield return Type.GetTypeFromCLSID(new Guid("DCA66D18-E253-4695-9E08-35B54420AFA2"));
+ }
+ }
+
+ [Fact]
+ public static void HasSameMetadataDefinitionAs__CornerCase_HasElementTypes()
+ {
+ // HasSameMetadataDefinitionAs on an array/byref/pointer type is uninteresting (they'll never be an actual member of a type)
+ // but for future compat, we'll establish their known behavior here. Since these types all return a MetadataToken of 0x02000000,
+ // they'll all "match" each other.
+
+ Type[] types =
+ {
+ typeof(int[]),
+ typeof(double[]),
+ typeof(int).MakeArrayType(1),
+ typeof(double).MakeArrayType(1),
+ typeof(int[,]),
+ typeof(double[,]),
+ typeof(int).MakeByRefType(),
+ typeof(double).MakeByRefType(),
+ typeof(int).MakePointerType(),
+ typeof(double).MakePointerType(),
+ };
+
+ Assert.All(types,
+ delegate (Type t1)
+ {
+ Assert.All(types, t2 => Assert.True(t1.HasSameMetadataDefinitionAs(t2)));
+ }
+ );
+ }
+
+ [Fact]
+ public static void HasSameMetadataDefinitionAs_CornerCase_ArrayMethods()
+ {
+ // The magic methods and constructors exposed on array types do not have metadata backing and report a MetadataToken of 0x06000000
+ // and hence compare identically with each other. This may be surprising but this test records that fact for future compat.
+ //
+ Type[] arrayTypes =
+ {
+ typeof(int[]),
+ typeof(double[]),
+ typeof(int).MakeArrayType(1),
+ typeof(double).MakeArrayType(1),
+ typeof(int[,]),
+ typeof(double[,]),
+ };
+
+ List<MemberInfo> members = new List<MemberInfo>();
+ foreach (Type arrayType in arrayTypes)
+ {
+ foreach (MemberInfo member in arrayType.GetMembers(BindingFlags.Public|BindingFlags.Instance | BindingFlags.DeclaredOnly))
+ {
+ if (member is MethodBase)
+ {
+ members.Add(member);
+ }
+ }
+ }
+
+ Assert.All(members,
+ delegate (MemberInfo member1)
+ {
+ Assert.All(members,
+ delegate (MemberInfo member2)
+ {
+ if (member1.MemberType == member2.MemberType)
+ Assert.True(member1.HasSameMetadataDefinitionAs(member2));
+ else
+ Assert.False(member1.HasSameMetadataDefinitionAs(member2));
+ }
+ );
+ }
+ );
+ }
+
+ [Fact]
+ [PlatformSpecific(TestPlatforms.Windows)]
+ public static void HasSameMetadataDefinitionAs_CornerCase_CLSIDConstructor()
+ {
+ // HasSameMetadataDefinitionAs on a GetTypeFromCLSID type is uninteresting (they'll never be an actual member of a type)
+ // but for future compat, we'll establish their known behavior here. Since these types and their constructors all return the same
+ // MetadataToken, they'll all "match" each other.
+
+ Type t1 = Type.GetTypeFromCLSID(new Guid("23A54889-7738-4F16-8AB2-CB23F8E756BE"));
+ Type t2 = Type.GetTypeFromCLSID(new Guid("DCA66D18-E253-4695-9E08-35B54420AFA2"));
+
+ Assert.True(t1.HasSameMetadataDefinitionAs(t2));
+
+ ConstructorInfo c1 = t1.GetConfirmedConstructor();
+ ConstructorInfo c2 = t2.GetConfirmedConstructor();
+
+ Assert.True(c1.HasSameMetadataDefinitionAs(c2));
+ }
+
+ private class TestClassWithGenericMethod<T>
+ {
+ public void Moo(T t) { }
+ public void Moo<M>(M m) { }
+ }
+
+ private class TestClass
+ {
+ public void Foo() { }
+ public void Foo(object o) { }
+ public void Foo(string s) { }
+ public void Bar() { }
+ }
+
+ private class TestClass2 { }
+
+
+ private class GenericTestClass<T>
+ {
+ [Marker(1)]
+ public void Foo(object o) { }
+ [Marker(2)]
+ public void Foo(int i) { }
+ [Marker(3)]
+ public void Foo(T t) { }
+ [Marker(4)]
+ public void Foo(double d) { }
+ [Marker(5)]
+ public void Foo(string s) { }
+ [Marker(6)]
+ public void Foo(int[] s) { }
+ [Marker(7)]
+ public void Foo<U>(U t) { }
+ [Marker(8)]
+ public void Foo<U>(T t) { }
+ [Marker(9)]
+ public void Foo<U, V>(T t) { }
+
+ [Marker(101)]
+ public GenericTestClass() { }
+ [Marker(102)]
+ public GenericTestClass(T t) { }
+ [Marker(103)]
+ public GenericTestClass(int t) { }
+
+ [Marker(201)]
+ public int Field1;
+ [Marker(202)]
+ public int Field2;
+ [Marker(203)]
+ public T Field3;
+
+ [Marker(301)]
+ public int Property1 { get { throw null; } set { throw null; } }
+ [Marker(302)]
+ public int Property2 { get { throw null; } set { throw null; } }
+ [Marker(303)]
+ public T Property3 { get { throw null; } set { throw null; } }
+
+ [Marker(401)]
+ public event Action Event1 { add { } remove { } }
+ [Marker(402)]
+ public event Action<int> Event2 { add { } remove { } }
+ [Marker(403)]
+ public event Action<T> Event3 { add { } remove { } }
+ }
+
+ private class DerivedFromGenericTestClass<T> : GenericTestClass<T> { }
+
private MemberInfo[] GetMembers(Type type)
{
return type.GetMembers(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
}
#pragma warning disable 0067, 0169
-#pragma warning disable 0067, 0169
[ComVisible(false)]
public class SampleClass
{
}
#pragma warning restore 0067, 0169
}
+
+ [AttributeUsage(AttributeTargets.All, AllowMultiple = false, Inherited = false)]
+ public class MarkerAttribute : Attribute
+ {
+ public MarkerAttribute(int mark)
+ {
+ Mark = mark;
+ }
+
+ public readonly int Mark;
+ }
+
+ internal static class Extensions
+ {
+ internal static bool HasSameMarkAs(this MemberInfo m1, MemberInfo m2)
+ {
+ MarkerAttribute marker1 = m1.GetCustomAttribute<MarkerAttribute>();
+ Assert.NotNull(marker1);
+
+ MarkerAttribute marker2 = m2.GetCustomAttribute<MarkerAttribute>();
+ Assert.NotNull(marker2);
+
+ return marker1.Mark == marker2.Mark;
+ }
+
+ internal static MethodInfo GetConfirmedMethod(this Type t, string name, params Type[] parameterTypes)
+ {
+ BindingFlags bf = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static | BindingFlags.ExactBinding;
+ MethodInfo method = t.GetMethod(name, bf, null, parameterTypes, null);
+ Assert.NotNull(method);
+ return method;
+ }
+
+ internal static ConstructorInfo GetConfirmedConstructor(this Type t, params Type[] parameterTypes)
+ {
+ BindingFlags bf = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.ExactBinding;
+ ConstructorInfo ctor = t.GetConstructor(bf, null, parameterTypes, null);
+ Assert.NotNull(ctor);
+ return ctor;
+ }
+
+ internal static IEnumerable<MemberInfo> GenerateTestMemberList(this Type t)
+ {
+ if (t.IsGenericTypeDefinition)
+ {
+ foreach (Type gp in t.GetTypeInfo().GenericTypeParameters)
+ {
+ yield return gp;
+ }
+ }
+ foreach (MemberInfo m in t.GetTypeInfo().DeclaredMembers)
+ {
+ yield return m;
+ MethodInfo method = m as MethodInfo;
+ if (method != null && method.IsGenericMethodDefinition)
+ {
+ foreach (Type mgp in method.GetGenericArguments())
+ {
+ yield return mgp;
+ }
+ yield return method.MakeGenericMethod(method.GetGenericArguments().Select(ga => typeof(object)).ToArray());
+ }
+ }
+ }
+ }
}
+++ /dev/null
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-using System.Linq;
-using System.Diagnostics;
-using System.Collections.Generic;
-
-using Xunit;
-
-#pragma warning disable 0649 // Yes, we know - test class have fields we don't assign to.
-
-namespace System.Reflection.Tests
-{
- public static class MemberInfoNetCoreAppTests
- {
- [Fact]
- public static void HasSameMetadataDefinitionAs_GenericClassMembers()
- {
- Type tGeneric = typeof(GenericTestClass<>);
- IEnumerable<MethodInfo> methodsOnGeneric = tGeneric.GetTypeInfo().GetDeclaredMethods(nameof(GenericTestClass<object>.Foo));
-
- List<Type> typeInsts = new List<Type>();
- foreach (MethodInfo method in methodsOnGeneric)
- {
- Debug.Assert(method.GetParameters().Length == 1);
- Type parameterType = method.GetParameters()[0].ParameterType;
- typeInsts.Add(tGeneric.MakeGenericType(parameterType));
- }
- typeInsts.Add(tGeneric);
- CrossTestHasSameMethodDefinitionAs(typeInsts.ToArray());
- }
-
- private static void CrossTestHasSameMethodDefinitionAs(params Type[] types)
- {
- Assert.All(types,
- delegate (Type type1)
- {
- Assert.All(type1.GenerateTestMemberList(),
- delegate (MemberInfo m1)
- {
- MarkerAttribute mark1 = m1.GetCustomAttribute<MarkerAttribute>();
- if (mark1 == null)
- return;
-
- Assert.All(types,
- delegate (Type type2)
- {
- Assert.All(type2.GenerateTestMemberList(),
- delegate (MemberInfo m2)
- {
- MarkerAttribute mark2 = m2.GetCustomAttribute<MarkerAttribute>();
- if (mark2 == null)
- return;
-
- bool hasSameMetadata = m1.HasSameMetadataDefinitionAs(m2);
- Assert.Equal(hasSameMetadata, m2.HasSameMetadataDefinitionAs(m1));
-
- if (hasSameMetadata)
- {
- Assert.Equal(mark1.Mark, mark2.Mark);
- }
- else
- {
- Assert.NotEqual(mark1.Mark, mark2.Mark);
- }
- }
- );
- }
- );
- }
- );
- }
- );
- }
-
- [Fact]
- public static void HasSameMetadataDefinitionAs_ReflectedTypeNotPartOfComparison()
- {
- Type tBase = typeof(GenericTestClass<>);
- Type tDerived = typeof(DerivedFromGenericTestClass<int>);
- BindingFlags bf = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance;
-
- IEnumerable<MemberInfo> baseMembers = tBase.GetMembers(bf).Where(m => m.IsDefined(typeof(MarkerAttribute)));
- baseMembers = baseMembers.Where(bm => !(bm is ConstructorInfo)); // Constructors cannot be seen from derived types.
- IEnumerable<MemberInfo> derivedMembers = tDerived.GetMembers(bf).Where(m => m.IsDefined(typeof(MarkerAttribute)));
- Assert.All(baseMembers,
- delegate (MemberInfo baseMember)
- {
- MemberInfo matchingDerivedMember = derivedMembers.Single(dm => dm.HasSameMarkAs(baseMember));
- Assert.True(baseMember.HasSameMetadataDefinitionAs(matchingDerivedMember));
- Assert.True(matchingDerivedMember.HasSameMetadataDefinitionAs(matchingDerivedMember));
- }
- );
- }
-
- [Fact]
- public static void HasSameMetadataDefinitionAs_ConstructedGenericMethods()
- {
- Type t1 = typeof(TestClassWithGenericMethod<>);
- Type theT = t1.GetTypeInfo().GenericTypeParameters[0];
-
- MethodInfo mooNormal = t1.GetConfirmedMethod(nameof(TestClassWithGenericMethod<object>.Moo), theT);
- MethodInfo mooGeneric = t1.GetTypeInfo().GetDeclaredMethods("Moo").Single(m => m.IsGenericMethod);
-
- MethodInfo mooInst = mooGeneric.MakeGenericMethod(typeof(int));
- Assert.True(mooGeneric.HasSameMetadataDefinitionAs(mooInst));
- Assert.True(mooInst.HasSameMetadataDefinitionAs(mooGeneric));
-
- MethodInfo mooInst2 = mooGeneric.MakeGenericMethod(typeof(double));
- Assert.True(mooInst2.HasSameMetadataDefinitionAs(mooInst));
- Assert.True(mooInst.HasSameMetadataDefinitionAs(mooInst2));
-
- Type t2 = typeof(TestClassWithGenericMethod<int>);
- MethodInfo mooNormalOnT2 = t2.GetConfirmedMethod(nameof(TestClassWithGenericMethod<object>.Moo), typeof(int));
- Assert.False(mooInst.HasSameMetadataDefinitionAs(mooNormalOnT2));
- }
-
- [Fact]
- public static void HasSameMetadataDefinitionAs_NamedAndGenericTypes()
- {
- Type tnong = typeof(TestClass);
- Type tnong2 = typeof(TestClass2);
- Type tg = typeof(GenericTestClass<>);
- Type tginst1 = typeof(GenericTestClass<int>);
- Type tginst2 = typeof(GenericTestClass<string>);
-
-
- Assert.True(tnong.HasSameMetadataDefinitionAs(tnong));
- Assert.True(tnong2.HasSameMetadataDefinitionAs(tnong2));
- Assert.True(tg.HasSameMetadataDefinitionAs(tg));
- Assert.True(tginst1.HasSameMetadataDefinitionAs(tginst1));
- Assert.True(tginst2.HasSameMetadataDefinitionAs(tginst2));
-
- Assert.True(tg.HasSameMetadataDefinitionAs(tginst1));
- Assert.True(tginst1.HasSameMetadataDefinitionAs(tginst1));
- Assert.True(tginst1.HasSameMetadataDefinitionAs(tginst2));
-
- Assert.False(tnong.HasSameMetadataDefinitionAs(tnong2));
- Assert.False(tnong.HasSameMetadataDefinitionAs(tg));
- Assert.False(tg.HasSameMetadataDefinitionAs(tnong));
- Assert.False(tnong.HasSameMetadataDefinitionAs(tginst1));
- Assert.False(tginst1.HasSameMetadataDefinitionAs(tnong));
- }
-
- [Fact]
- public static void HasSameMetadataDefinitionAs_GenericTypeParameters()
- {
- Type theT = typeof(GenericTestClass<>).GetTypeInfo().GenericTypeParameters[0];
- Type theT2 = typeof(TestClassWithGenericMethod<>).GetTypeInfo().GenericTypeParameters[0];
-
- BindingFlags bf = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance | BindingFlags.DeclaredOnly | BindingFlags.ExactBinding;
- MethodInfo mooNong = theT2.GetMethod("Moo", bf, null, new Type[] { theT2 }, null);
- MethodInfo mooGeneric = typeof(TestClassWithGenericMethod<>).GetTypeInfo().GetDeclaredMethods("Moo").Single(m => m.IsGenericMethod);
- Type theM = mooGeneric.GetGenericArguments()[0];
-
- Assert.True(theT.HasSameMetadataDefinitionAs(theT));
- Assert.False(theT2.HasSameMetadataDefinitionAs(theT));
- Assert.False(theT.HasSameMetadataDefinitionAs(theT2));
- Assert.False(theM.HasSameMetadataDefinitionAs(theT));
- Assert.False(theM.HasSameMetadataDefinitionAs(theT2));
- Assert.False(theT2.HasSameMetadataDefinitionAs(theM));
- Assert.False(theT.HasSameMetadataDefinitionAs(theM));
- }
-
- [Fact]
- public static void HasSameMetadataDefinitionAs_Twins()
- {
- // This situation is particularly treacherous for CoreRT as the .NET Native toolchain can and does assign
- // the same native metadata tokens to identically structured members in unrelated types.
- Type twin1 = typeof(Twin1);
- Type twin2 = typeof(Twin2);
-
- Assert.All(twin1.GenerateTestMemberList(),
- delegate (MemberInfo m1)
- {
- Assert.All(twin2.GenerateTestMemberList(),
- delegate (MemberInfo m2)
- {
- Assert.False(m1.HasSameMetadataDefinitionAs(m2));
- }
- );
- }
- );
- }
-
- private class Twin1
- {
- public Twin1() { }
- public int Field1;
- public Action Event1;
- public void Method1() { }
- public int Property1 { get; set; }
- }
-
- private class Twin2
- {
- public Twin2() { }
- public int Field1;
- public Action Event1;
- public void Method1() { }
- public int Property1 { get; set; }
- }
-
- [Fact]
- [OuterLoop] // Time-consuming.
- public static void HasSameMetadataDefinitionAs_CrossAssembly()
- {
- // Make sure that identical tokens in different assemblies don't confuse the api.
- foreach (Type t1 in typeof(object).Assembly.DefinedTypes)
- {
- foreach (Type t2 in typeof(MemberInfoNetCoreAppTests).Assembly.DefinedTypes)
- {
- Assert.False(t1.HasSameMetadataDefinitionAs(t2));
- }
- }
- }
-
- [Theory]
- [MemberData(nameof(NegativeTypeData))]
- public static void HasSameMetadataDefinitionAs_Negative_NonRuntimeType(Type type)
- {
- Type mockType = new MockType();
- Assert.False(type.HasSameMetadataDefinitionAs(mockType));
- Assert.All(type.GenerateTestMemberList(),
- delegate (MemberInfo member)
- {
- Assert.False(member.HasSameMetadataDefinitionAs(mockType));
- }
- );
- }
-
- [Theory]
- [MemberData(nameof(NegativeTypeData))]
- public static void HasSameMetadataDefinitionAs_Negative_Null(Type type)
- {
- AssertExtensions.Throws<ArgumentNullException>("other", () => type.HasSameMetadataDefinitionAs(null));
- Assert.All(type.GenerateTestMemberList(),
- delegate (MemberInfo member)
- {
- AssertExtensions.Throws<ArgumentNullException>("other", () => member.HasSameMetadataDefinitionAs(null));
- }
- );
- }
-
- public static IEnumerable<object[]> NegativeTypeData => NegativeTypeDataRaw.Select(t => new object[] { t });
- private static IEnumerable<Type> NegativeTypeDataRaw
- {
- get
- {
- yield return typeof(TestClass);
- yield return typeof(GenericTestClass<>);
- yield return typeof(GenericTestClass<int>);
-
- yield return typeof(int[]);
- yield return typeof(int).MakeArrayType(1);
- yield return typeof(int[,]);
- yield return typeof(int).MakeByRefType();
- yield return typeof(int).MakePointerType();
-
- yield return typeof(GenericTestClass<>).GetTypeInfo().GenericTypeParameters[0];
- if (PlatformDetection.IsWindows)
- yield return Type.GetTypeFromCLSID(new Guid("DCA66D18-E253-4695-9E08-35B54420AFA2"));
- }
- }
-
- [Fact]
- public static void HasSameMetadataDefinitionAs__CornerCase_HasElementTypes()
- {
- // HasSameMetadataDefinitionAs on an array/byref/pointer type is uninteresting (they'll never be an actual member of a type)
- // but for future compat, we'll establish their known behavior here. Since these types all return a MetadataToken of 0x02000000,
- // they'll all "match" each other.
-
- Type[] types =
- {
- typeof(int[]),
- typeof(double[]),
- typeof(int).MakeArrayType(1),
- typeof(double).MakeArrayType(1),
- typeof(int[,]),
- typeof(double[,]),
- typeof(int).MakeByRefType(),
- typeof(double).MakeByRefType(),
- typeof(int).MakePointerType(),
- typeof(double).MakePointerType(),
- };
-
- Assert.All(types,
- delegate (Type t1)
- {
- Assert.All(types, t2 => Assert.True(t1.HasSameMetadataDefinitionAs(t2)));
- }
- );
- }
-
- [Fact]
- public static void HasSameMetadataDefinitionAs_CornerCase_ArrayMethods()
- {
- // The magic methods and constructors exposed on array types do not have metadata backing and report a MetadataToken of 0x06000000
- // and hence compare identically with each other. This may be surprising but this test records that fact for future compat.
- //
- Type[] arrayTypes =
- {
- typeof(int[]),
- typeof(double[]),
- typeof(int).MakeArrayType(1),
- typeof(double).MakeArrayType(1),
- typeof(int[,]),
- typeof(double[,]),
- };
-
- List<MemberInfo> members = new List<MemberInfo>();
- foreach (Type arrayType in arrayTypes)
- {
- foreach (MemberInfo member in arrayType.GetMembers(BindingFlags.Public|BindingFlags.Instance | BindingFlags.DeclaredOnly))
- {
- if (member is MethodBase)
- {
- members.Add(member);
- }
- }
- }
-
- Assert.All(members,
- delegate (MemberInfo member1)
- {
- Assert.All(members,
- delegate (MemberInfo member2)
- {
- if (member1.MemberType == member2.MemberType)
- Assert.True(member1.HasSameMetadataDefinitionAs(member2));
- else
- Assert.False(member1.HasSameMetadataDefinitionAs(member2));
- }
- );
- }
- );
- }
-
- [Fact]
- [PlatformSpecific(TestPlatforms.Windows)]
- public static void HasSameMetadataDefinitionAs_CornerCase_CLSIDConstructor()
- {
- // HasSameMetadataDefinitionAs on a GetTypeFromCLSID type is uninteresting (they'll never be an actual member of a type)
- // but for future compat, we'll establish their known behavior here. Since these types and their constructors all return the same
- // MetadataToken, they'll all "match" each other.
-
- Type t1 = Type.GetTypeFromCLSID(new Guid("23A54889-7738-4F16-8AB2-CB23F8E756BE"));
- Type t2 = Type.GetTypeFromCLSID(new Guid("DCA66D18-E253-4695-9E08-35B54420AFA2"));
-
- Assert.True(t1.HasSameMetadataDefinitionAs(t2));
-
- ConstructorInfo c1 = t1.GetConfirmedConstructor();
- ConstructorInfo c2 = t2.GetConfirmedConstructor();
-
- Assert.True(c1.HasSameMetadataDefinitionAs(c2));
- }
-
-
- private static bool HasSameMarkAs(this MemberInfo m1, MemberInfo m2)
- {
- MarkerAttribute marker1 = m1.GetCustomAttribute<MarkerAttribute>();
- Assert.NotNull(marker1);
-
- MarkerAttribute marker2 = m2.GetCustomAttribute<MarkerAttribute>();
- Assert.NotNull(marker2);
-
- return marker1.Mark == marker2.Mark;
- }
-
- private static MethodInfo GetConfirmedMethod(this Type t, string name, params Type[] parameterTypes)
- {
- BindingFlags bf = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static | BindingFlags.ExactBinding;
- MethodInfo method = t.GetMethod(name, bf, null, parameterTypes, null);
- Assert.NotNull(method);
- return method;
- }
-
- private static ConstructorInfo GetConfirmedConstructor(this Type t, params Type[] parameterTypes)
- {
- BindingFlags bf = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.ExactBinding;
- ConstructorInfo ctor = t.GetConstructor(bf, null, parameterTypes, null);
- Assert.NotNull(ctor);
- return ctor;
- }
-
- private static IEnumerable<MemberInfo> GenerateTestMemberList(this Type t)
- {
- if (t.IsGenericTypeDefinition)
- {
- foreach (Type gp in t.GetTypeInfo().GenericTypeParameters)
- {
- yield return gp;
- }
- }
- foreach (MemberInfo m in t.GetTypeInfo().DeclaredMembers)
- {
- yield return m;
- MethodInfo method = m as MethodInfo;
- if (method != null && method.IsGenericMethodDefinition)
- {
- foreach (Type mgp in method.GetGenericArguments())
- {
- yield return mgp;
- }
- yield return method.MakeGenericMethod(method.GetGenericArguments().Select(ga => typeof(object)).ToArray());
- }
- }
- }
-
- private class TestClassWithGenericMethod<T>
- {
- public void Moo(T t) { }
- public void Moo<M>(M m) { }
- }
-
- private class TestClass
- {
- public void Foo() { }
- public void Foo(object o) { }
- public void Foo(string s) { }
- public void Bar() { }
- }
-
- private class TestClass2 { }
-
-
- private class GenericTestClass<T>
- {
- [Marker(1)]
- public void Foo(object o) { }
- [Marker(2)]
- public void Foo(int i) { }
- [Marker(3)]
- public void Foo(T t) { }
- [Marker(4)]
- public void Foo(double d) { }
- [Marker(5)]
- public void Foo(string s) { }
- [Marker(6)]
- public void Foo(int[] s) { }
- [Marker(7)]
- public void Foo<U>(U t) { }
- [Marker(8)]
- public void Foo<U>(T t) { }
- [Marker(9)]
- public void Foo<U, V>(T t) { }
-
- [Marker(101)]
- public GenericTestClass() { }
- [Marker(102)]
- public GenericTestClass(T t) { }
- [Marker(103)]
- public GenericTestClass(int t) { }
-
- [Marker(201)]
- public int Field1;
- [Marker(202)]
- public int Field2;
- [Marker(203)]
- public T Field3;
-
- [Marker(301)]
- public int Property1 { get { throw null; } set { throw null; } }
- [Marker(302)]
- public int Property2 { get { throw null; } set { throw null; } }
- [Marker(303)]
- public T Property3 { get { throw null; } set { throw null; } }
-
- [Marker(401)]
- public event Action Event1 { add { } remove { } }
- [Marker(402)]
- public event Action<int> Event2 { add { } remove { } }
- [Marker(403)]
- public event Action<T> Event3 { add { } remove { } }
- }
-
- private class DerivedFromGenericTestClass<T> : GenericTestClass<T> { }
-
- [AttributeUsage(AttributeTargets.All, AllowMultiple = false, Inherited = false)]
- public class MarkerAttribute : Attribute
- {
- public MarkerAttribute(int mark)
- {
- Mark = mark;
- }
-
- public readonly int Mark;
- }
- }
-}
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
- <Compile Include="AssemblyTests.netcoreapp.cs" />
- <Compile Include="MemberInfoTests.netcoreapp.cs" />
- <Compile Include="TypeInfoTests.netcoreapp.cs" />
- </ItemGroup>
- <ItemGroup>
<ProjectReference Include="AssemblyVersion\System.Reflection.Tests.Assembly_0_0_0_0.csproj" />
<ProjectReference Include="AssemblyVersion\System.Reflection.Tests.Assembly_1_0_0_0.csproj" />
<ProjectReference Include="AssemblyVersion\System.Reflection.Tests.Assembly_1_1_0_0.csproj" />
Assert.Equal(expected, type.GetTypeInfo().UnderlyingSystemType);
}
+ public static IEnumerable<object[]> SZArrayOrNotTypes()
+ {
+ yield return new object[] { typeof(int[]), true };
+ yield return new object[] { typeof(string[]), true };
+ yield return new object[] { typeof(void), false };
+ yield return new object[] { typeof(int), false };
+ yield return new object[] { typeof(int[]).MakeByRefType(), false };
+ yield return new object[] { typeof(int[,]), false };
+ yield return new object[] { typeof(TypeInfoTests), false };
+ if (PlatformDetection.IsNonZeroLowerBoundArraySupported)
+ {
+ yield return new object[] { Array.CreateInstance(typeof(int), new[] { 2 }, new[] { -1 }).GetType(), false };
+ yield return new object[] { Array.CreateInstance(typeof(int), new[] { 2 }, new[] { 1 }).GetType(), false };
+ }
+ yield return new object[] { Array.CreateInstance(typeof(int), new[] { 2 }, new[] { 0 }).GetType(), true };
+ yield return new object[] { typeof(int[][]), true };
+ yield return new object[] { Type.GetType("System.Int32[]"), true };
+ yield return new object[] { Type.GetType("System.Int32[*]"), false };
+ yield return new object[] { Type.GetType("System.Int32"), false };
+ yield return new object[] { typeof(int).MakeArrayType(), true };
+ yield return new object[] { typeof(int).MakeArrayType(1), false };
+ yield return new object[] { typeof(int).MakeArrayType().MakeArrayType(), true };
+ yield return new object[] { typeof(int).MakeArrayType(2), false };
+ yield return new object[] { typeof(OutsideTypeInfoTests<int>.InsideTypeInfoTests<string>), false };
+ yield return new object[] { typeof(OutsideTypeInfoTests<int>.InsideTypeInfoTests<string>[]), true };
+ yield return new object[] { typeof(OutsideTypeInfoTests<int>.InsideTypeInfoTests<string>[,]), false };
+ if (PlatformDetection.IsNonZeroLowerBoundArraySupported)
+ {
+ yield return new object[] { Array.CreateInstance(typeof(OutsideTypeInfoTests<int>.InsideTypeInfoTests<string>), new[] { 2 }, new[] { -1 }).GetType(), false };
+ }
+ }
+
+ [Theory, MemberData(nameof(SZArrayOrNotTypes))]
+ public void IsSZArray(Type type, bool expected)
+ {
+ Assert.Equal(expected, type.GetTypeInfo().IsSZArray);
+ }
+
#pragma warning disable 0067, 0169
public static class ClassWithStaticConstructor
{
public class AbstractSubSubClass : AbstractSubClass { }
}
#pragma warning restore 0067, 0169
+
+ public class OutsideTypeInfoTests
+ {
+ public class InsideTypeInfoTests { }
+ }
+
+ public class OutsideTypeInfoTests<T>
+ {
+ public class InsideTypeInfoTests<U> { }
+ }
}
+++ /dev/null
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-using System.Collections.Generic;
-using Xunit;
-
-namespace System.Reflection.Tests
-{
- public class TypeInfoNetcoreTests
- {
- public static IEnumerable<object[]> SZArrayOrNotTypes()
- {
- yield return new object[] { typeof(int[]), true };
- yield return new object[] { typeof(string[]), true };
- yield return new object[] { typeof(void), false };
- yield return new object[] { typeof(int), false };
- yield return new object[] { typeof(int[]).MakeByRefType(), false };
- yield return new object[] { typeof(int[,]), false };
- yield return new object[] { typeof(TypeInfoTests), false };
- if (PlatformDetection.IsNonZeroLowerBoundArraySupported)
- {
- yield return new object[] { Array.CreateInstance(typeof(int), new[] { 2 }, new[] { -1 }).GetType(), false };
- yield return new object[] { Array.CreateInstance(typeof(int), new[] { 2 }, new[] { 1 }).GetType(), false };
- }
- yield return new object[] { Array.CreateInstance(typeof(int), new[] { 2 }, new[] { 0 }).GetType(), true };
- yield return new object[] { typeof(int[][]), true };
- yield return new object[] { Type.GetType("System.Int32[]"), true };
- yield return new object[] { Type.GetType("System.Int32[*]"), false };
- yield return new object[] { Type.GetType("System.Int32"), false };
- yield return new object[] { typeof(int).MakeArrayType(), true };
- yield return new object[] { typeof(int).MakeArrayType(1), false };
- yield return new object[] { typeof(int).MakeArrayType().MakeArrayType(), true };
- yield return new object[] { typeof(int).MakeArrayType(2), false };
- yield return new object[] { typeof(OutsideTypeInfoNetcoreTests<int>.InsideTypeInfoNetcoreTests<string>), false };
- yield return new object[] { typeof(OutsideTypeInfoNetcoreTests<int>.InsideTypeInfoNetcoreTests<string>[]), true };
- yield return new object[] { typeof(OutsideTypeInfoNetcoreTests<int>.InsideTypeInfoNetcoreTests<string>[,]), false };
- if (PlatformDetection.IsNonZeroLowerBoundArraySupported)
- {
- yield return new object[] { Array.CreateInstance(typeof(OutsideTypeInfoNetcoreTests<int>.InsideTypeInfoNetcoreTests<string>), new[] { 2 }, new[] { -1 }).GetType(), false };
- }
- }
-
- [Theory, MemberData(nameof(SZArrayOrNotTypes))]
- public void IsSZArray(Type type, bool expected)
- {
- Assert.Equal(expected, type.GetTypeInfo().IsSZArray);
- }
- }
-
- public class OutsideTypeInfoNetcoreTests
- {
- public class InsideTypeInfoNetcoreTests { }
- }
-
- public class OutsideTypeInfoNetcoreTests<T>
- {
- public class InsideTypeInfoNetcoreTests<U> { }
- }
-}