CodeType Gets Common Parameters

We are using Visual Studio CodeModel and have some problems getting general CodeType parameters. How to get them indiscriminately FullName themselves?

It is highlighted (although not checked) in How do I get general restrictions from CodeInterface as a CodeType object? that there is no other way, however, this is actually not believable, like:

System.Func<Outer.Inner>

it wonโ€™t be determined: you cannot know whether the generic parameter that you analyzed ( Outer.Inner ) refers to the Outer namespace containing the Inner class, or if it belongs to the Outer class that has the Inner inner class (and yes, this is not Outer+Inner in such cases).

If someone even knows how to tell the FullName property to display nested classes with a + sign, that would be great too.

+7
generics c # envdte
source share
2 answers

I think the answer here is pretty definite. This is not supported by DTE or DTE2 and is unlikely to be supported in the future.

The only way now is to use Roslyn, which is not acceptable for those of us who do not want to use pre-release software. I also did not study what dependencies could entail (do users of my component need to install Roslyn?).

You can use a regular expression to get types from a FullName string. But for those of us in the real world who need a token ( T ) for a particular type ( System.String ), this is not an option.

0
source share

I cannot find a way to do this for any generic type, but if you need to do this for a specific type, this is possible in some cases.

For example, I have the following code to check if a type is a collection, and if so, get the element type:

  private static bool IsCollectionType(CodeType type, out CodeType elementType) { // string implements IEnumerable<char>, but we don't want to treat it as a collection if (type.FullName == "System.String") { elementType = null; return false; } var enumerable = type.Bases.OfType<CodeInterface>().FirstOrDefault(i => i.FullName.StartsWith("System.Collections.Generic.IEnumerable<")); var method = enumerable?.Members.OfType<CodeFunction>().FirstOrDefault(m => m.Name == "GetEnumerator"); var enumerator = method?.Type.CodeType; var current = enumerator?.Members.OfType<CodeProperty>().FirstOrDefault(m => m.Name == "Current"); if (current != null) { elementType = current.Type.CodeType; return true; } elementType = null; return false; } 

As you can see, I do not directly consider the generic type argument, but instead I look at the IEnumerable<T>.GetEnumerator().Current . Of course, this requires specific knowledge of the type you are working with.

0
source share

All Articles