This repository was archived by the owner on Feb 25, 2026. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Support for nested/pointer/byref types for Type.ToTypeString() #3468
Merged
7 commits merged into
CommunityToolkit:master
from
Sergio0694:bugfix/totypestring-extension
Oct 2, 2020
Merged
Changes from all commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
b6c7859
Minor code refactoring in unit tests
Sergio0694 e8f98f2
Added support for nested types
Sergio0694 15f90f3
Added support for void type
Sergio0694 7c090e7
Added support for pointer and by-ref types
Sergio0694 9e045fa
Fixed unwanted capture in lambda expression
Sergio0694 e74eb65
Added llamas
Sergio0694 2f4a887
Merge branch 'master' into bugfix/totypestring-extension
Rosuavio File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -4,7 +4,6 @@ | |
|
|
||
| using System; | ||
| using System.Collections.Generic; | ||
| using System.Diagnostics.CodeAnalysis; | ||
| using Microsoft.Toolkit.Extensions; | ||
| using Microsoft.VisualStudio.TestTools.UnitTesting; | ||
|
|
||
|
|
@@ -15,32 +14,148 @@ public class Test_TypeExtensions | |
| { | ||
| [TestCategory("TypeExtensions")] | ||
| [TestMethod] | ||
| public void Test_TypeExtensions_BuiltInTypes() | ||
| [DataRow("bool", typeof(bool))] | ||
| [DataRow("int", typeof(int))] | ||
| [DataRow("float", typeof(float))] | ||
| [DataRow("double", typeof(double))] | ||
| [DataRow("decimal", typeof(decimal))] | ||
| [DataRow("object", typeof(object))] | ||
| [DataRow("string", typeof(string))] | ||
| [DataRow("void", typeof(void))] | ||
| public void Test_TypeExtensions_BuiltInTypes(string name, Type type) | ||
| { | ||
| Assert.AreEqual("bool", typeof(bool).ToTypeString()); | ||
| Assert.AreEqual("int", typeof(int).ToTypeString()); | ||
| Assert.AreEqual("float", typeof(float).ToTypeString()); | ||
| Assert.AreEqual("double", typeof(double).ToTypeString()); | ||
| Assert.AreEqual("decimal", typeof(decimal).ToTypeString()); | ||
| Assert.AreEqual("object", typeof(object).ToTypeString()); | ||
| Assert.AreEqual("string", typeof(string).ToTypeString()); | ||
| Assert.AreEqual(name, type.ToTypeString()); | ||
| } | ||
|
|
||
| [TestCategory("TypeExtensions")] | ||
| [TestMethod] | ||
| [SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1009", Justification = "Nullable value tuple type")] | ||
| public void Test_TypeExtensions_GenericTypes() | ||
| [DataRow("int?", typeof(int?))] | ||
| [DataRow("System.DateTime?", typeof(DateTime?))] | ||
| [DataRow("(int, float)", typeof((int, float)))] | ||
| [DataRow("(double?, string, int)?", typeof((double?, string, int)?))] | ||
| [DataRow("int[]", typeof(int[]))] | ||
| [DataRow("int[,]", typeof(int[,]))] | ||
| [DataRow("System.Span<float>", typeof(Span<float>))] | ||
| [DataRow("System.Memory<char>", typeof(Memory<char>))] | ||
| [DataRow("System.Collections.Generic.IEnumerable<int>", typeof(IEnumerable<int>))] | ||
| [DataRow("System.Collections.Generic.Dictionary<int, System.Collections.Generic.List<float>>", typeof(Dictionary<int, List<float>>))] | ||
| public void Test_TypeExtensions_GenericTypes(string name, Type type) | ||
| { | ||
| Assert.AreEqual("int?", typeof(int?).ToTypeString()); | ||
| Assert.AreEqual("System.DateTime?", typeof(DateTime?).ToTypeString()); | ||
| Assert.AreEqual("(int, float)", typeof((int, float)).ToTypeString()); | ||
| Assert.AreEqual("(double?, string, int)?", typeof((double?, string, int)?).ToTypeString()); | ||
| Assert.AreEqual("int[]", typeof(int[]).ToTypeString()); | ||
| Assert.AreEqual(typeof(int[,]).ToTypeString(), "int[,]"); | ||
| Assert.AreEqual("System.Span<float>", typeof(Span<float>).ToTypeString()); | ||
| Assert.AreEqual("System.Memory<char>", typeof(Memory<char>).ToTypeString()); | ||
| Assert.AreEqual("System.Collections.Generic.IEnumerable<int>", typeof(IEnumerable<int>).ToTypeString()); | ||
| Assert.AreEqual(typeof(Dictionary<int, List<float>>).ToTypeString(), "System.Collections.Generic.Dictionary<int, System.Collections.Generic.List<float>>"); | ||
| Assert.AreEqual(name, type.ToTypeString()); | ||
| } | ||
|
|
||
| [TestCategory("TypeExtensions")] | ||
| [TestMethod] | ||
| [DataRow("UnitTests.Extensions.Test_TypeExtensions.Animal", typeof(Animal))] | ||
| [DataRow("UnitTests.Extensions.Test_TypeExtensions.Animal.Cat", typeof(Animal.Cat))] | ||
| [DataRow("UnitTests.Extensions.Test_TypeExtensions.Animal.Dog", typeof(Animal.Dog))] | ||
| [DataRow("UnitTests.Extensions.Test_TypeExtensions.Animal.Rabbit<int?>", typeof(Animal.Rabbit<int?>))] | ||
| [DataRow("UnitTests.Extensions.Test_TypeExtensions.Animal.Rabbit<string>", typeof(Animal.Rabbit<string>))] | ||
| [DataRow("UnitTests.Extensions.Test_TypeExtensions.Animal.Rabbit<int>.Foo", typeof(Animal.Rabbit<int>.Foo))] | ||
| [DataRow("UnitTests.Extensions.Test_TypeExtensions.Animal.Rabbit<(string, int)?>.Foo", typeof(Animal.Rabbit<(string, int)?>.Foo))] | ||
| [DataRow("UnitTests.Extensions.Test_TypeExtensions.Animal.Rabbit<int>.Foo<string>", typeof(Animal.Rabbit<int>.Foo<string>))] | ||
| [DataRow("UnitTests.Extensions.Test_TypeExtensions.Animal.Rabbit<int>.Foo<int[]>", typeof(Animal.Rabbit<int>.Foo<int[]>))] | ||
| [DataRow("UnitTests.Extensions.Test_TypeExtensions.Animal.Rabbit<string[]>.Foo<object>", typeof(Animal.Rabbit<string[]>.Foo<object>))] | ||
| [DataRow("UnitTests.Extensions.Test_TypeExtensions.Animal.Rabbit<(string, int)?>.Foo<(int, int?)>", typeof(Animal.Rabbit<(string, int)?>.Foo<(int, int?)>))] | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No 🦙? 😒
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. jk
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Too late! e74eb65 🙈 |
||
| [DataRow("UnitTests.Extensions.Test_TypeExtensions.Animal.Llama<float, System.DateTime>", typeof(Animal.Llama<float, DateTime>))] | ||
| [DataRow("UnitTests.Extensions.Test_TypeExtensions.Animal.Llama<string, (int?, object)>", typeof(Animal.Llama<string, (int?, object)>))] | ||
| [DataRow("UnitTests.Extensions.Test_TypeExtensions.Animal.Llama<string, (int?, object)?>.Foo", typeof(Animal.Llama<string, (int?, object)?>.Foo))] | ||
| [DataRow("UnitTests.Extensions.Test_TypeExtensions.Animal.Llama<float, System.DateTime>.Foo", typeof(Animal.Llama<float, DateTime>.Foo))] | ||
| [DataRow("UnitTests.Extensions.Test_TypeExtensions.Animal.Llama<string, (int?, object)?>.Foo<string>", typeof(Animal.Llama<string, (int?, object)?>.Foo<string>))] | ||
| [DataRow("UnitTests.Extensions.Test_TypeExtensions.Animal.Llama<float, System.DateTime>.Foo<(float?, int)?>", typeof(Animal.Llama<float, DateTime>.Foo<(float?, int)?>))] | ||
| [DataRow("UnitTests.Extensions.Test_TypeExtensions.Vehicle<double>", typeof(Vehicle<double>))] | ||
| [DataRow("UnitTests.Extensions.Test_TypeExtensions.Vehicle<int?>[]", typeof(Vehicle<int?>[]))] | ||
| [DataRow("System.Collections.Generic.List<UnitTests.Extensions.Test_TypeExtensions.Vehicle<int>>", typeof(List<Vehicle<int>>))] | ||
| [DataRow("System.Collections.Generic.List<UnitTests.Extensions.Test_TypeExtensions.Animal.Rabbit<int?>>", typeof(List<Animal.Rabbit<int?>>))] | ||
| [DataRow("System.Collections.Generic.List<UnitTests.Extensions.Test_TypeExtensions.Animal.Llama<float, System.DateTime[]>>", typeof(List<Animal.Llama<float, DateTime[]>>))] | ||
| public void Test_TypeExtensions_NestedTypes(string name, Type type) | ||
| { | ||
| Assert.AreEqual(name, type.ToTypeString()); | ||
| } | ||
|
|
||
| #pragma warning disable SA1015 // Closing generic brackets should be spaced correctly | ||
| [TestCategory("TypeExtensions")] | ||
| [TestMethod] | ||
| [DataRow("void*", typeof(void*))] | ||
| [DataRow("int**", typeof(int**))] | ||
| [DataRow("byte***", typeof(byte***))] | ||
| [DataRow("System.Guid*", typeof(Guid*))] | ||
| [DataRow("UnitTests.Extensions.Foo<int>*", typeof(Foo<int>*))] | ||
| [DataRow("UnitTests.Extensions.Test_TypeExtensions.Animal.Cat**", typeof(Animal.Cat**))] | ||
| [DataRow("UnitTests.Extensions.Test_TypeExtensions.Animal.Cat<int>*", typeof(Animal.Cat<int>*))] | ||
| [DataRow("UnitTests.Extensions.Test_TypeExtensions.Animal.Cat<float>.Bar**", typeof(Animal.Cat<float>.Bar**))] | ||
| [DataRow("UnitTests.Extensions.Test_TypeExtensions.Animal.Cat<double>.Bar<int>***", typeof(Animal.Cat<double>.Bar<int>***))] | ||
| public void Test_TypeExtensions_PointerTypes(string name, Type type) | ||
| { | ||
| Assert.AreEqual(name, type.ToTypeString()); | ||
| } | ||
| #pragma warning restore SA1015 | ||
|
|
||
| [TestCategory("TypeExtensions")] | ||
| [TestMethod] | ||
| [DataRow("int&", typeof(int))] | ||
| [DataRow("byte&", typeof(byte))] | ||
| [DataRow("System.Guid&", typeof(Guid))] | ||
| [DataRow("UnitTests.Extensions.Foo<int>&", typeof(Foo<int>))] | ||
| [DataRow("UnitTests.Extensions.Test_TypeExtensions.Animal.Cat&", typeof(Animal.Cat))] | ||
| [DataRow("UnitTests.Extensions.Test_TypeExtensions.Animal.Cat<int>&", typeof(Animal.Cat<int>))] | ||
| [DataRow("UnitTests.Extensions.Test_TypeExtensions.Animal.Cat<float>.Bar&", typeof(Animal.Cat<float>.Bar))] | ||
| [DataRow("UnitTests.Extensions.Test_TypeExtensions.Animal.Cat<double>.Bar<int>&", typeof(Animal.Cat<double>.Bar<int>))] | ||
| public void Test_TypeExtensions_RefTypes(string name, Type type) | ||
| { | ||
| Assert.AreEqual(name, type.MakeByRefType().ToTypeString()); | ||
| } | ||
|
|
||
| private class Animal | ||
| { | ||
| public struct Cat | ||
| { | ||
| } | ||
|
|
||
| public struct Cat<T1> | ||
| { | ||
| public struct Bar | ||
| { | ||
| } | ||
|
|
||
| public struct Bar<T2> | ||
| { | ||
| } | ||
| } | ||
|
|
||
| public class Dog | ||
| { | ||
| } | ||
|
|
||
| public class Rabbit<T> | ||
| { | ||
| public class Foo | ||
| { | ||
| } | ||
|
|
||
| public class Foo<T2> | ||
| { | ||
| } | ||
| } | ||
|
|
||
| public class Llama<T1, T2> | ||
| { | ||
| public class Foo | ||
| { | ||
| } | ||
|
|
||
| public class Foo<T3> | ||
| { | ||
| } | ||
| } | ||
| } | ||
|
|
||
| private class Vehicle<T> | ||
| { | ||
| } | ||
| } | ||
|
|
||
| internal struct Foo<T> | ||
| { | ||
| } | ||
| } | ||
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is the output here significantly different or just better formatted here? i.e. if someone with 6.1 upgrades, will the result be different in the cases where things worked?
(Just want to check if we should mark this as a breaking change even though the API surface itself didn't change.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The output should be the same for types that were properly supported already 😊
In that line I'm explicitly adding the namespace just because with this change we're now using the name of each type directly instead of the fullname (so that we can manually traverse each type in case of nested types), so we need to add the namespace at the start ourselves to match the previous output with the fully qualified name.
As for changes between this PR and the previous version, here's some examples.
I'm only displaying cases with actual differences, such as nested types or pointer/ref types:
In general, some cases just look nicer (eg.
.instead of+for a simple nested type, orvoidinstead ofSystem.Void), while others are now actually correct, whereas currently they are either missing bits (eg. nested types getting lost in the process) and/or displayed with wrong type arguments (they're basically all combined together).