Visual Studio SDK get type modifier information - is type abstract or internal?

谁说胖子不能爱 提交于 2020-04-18 12:35:36

问题


I use the IVsObjectList2.GetCategoryField2 method to retrieve different information of a type.

Now I wonder how I can retrieve C# specific information like abstract or internal modifier of a type? The Object Browser can displays this informations.

Update 1:

I have made another attempt to get this information. Via the DynamicTypeService and the IVsHierarchy (of the project) I can get the TypeResolutionService. This can then return the Type I'm are looking for, and form the Type I get the infomrations (internal, abstract, etc.)

Unfortunately, this only works with .NET Framework projects. .NET Core projects don't work. The assumption is that .NET core projects cause problems when resolving, because the VS add-in (or Visual Studio SDK) run under .NET Framework.

var dte = Package.GetGlobalService(typeof(DTE)) as DTE2;
var serviceProvider = new ServiceProvider((Microsoft.VisualStudio.OLE.Interop.IServiceProvider)dte);

IVsSimpleObjectList2 objectList;
....
objectList.CountSourceItems(index, out var vsHierarchy, out var itemid, out var pcItems);

DynamicTypeService dynamicTypeService = (DynamicTypeService)serviceProvider.GetService(typeof(DynamicTypeService));
var typeResolutionService = dynamicTypeService.GetTypeResolutionService(hier);
var type = typeResolutionService.GetType("ObjectBuilder.ObjectBrowserTestTypes.AbstractTestClass");

More Infos here: Visual Studio Extension get all classes and interfaces metadata

I'm still looking for a solution. Does anyone have another idea?


回答1:


At the end, I decided not to retrieve the information about the types via the Object-Browser or IVsObjectManager2. The reason is that I didn't get all the information I needed.

For types in the currently loaded visual studio projects I'm using the ElementClass or CodeClass class.

var service = Package.GetGlobalService(typeof(DTE)) as DTE2;
Project project = service?.Solution?.Projects.Item(0);
CodeType codeType = project.CodeModel.CodeTypeFromFullName("Full name of Type");

if (codeType.Kind == vsCMElement.vsCMElementClass && codeType is CodeClass2 codeClass)
{
    // get all the information form the code class
    var typeDescription = new TypeDescription();
    typeDescription.FullName = codeClass.FullName;
    typeDescription.ContainsGenericParameters = codeClass.IsGeneric;
    typeDescription.IsAbstract = codeClass.IsAbstract;
}

For types that are in a referenced assembly I'm using Mono.Cecil. The advantage of Mono.Cecil is, that it works with .NET Framework DLLs and .NET Core DLLs. The path of the referenced assembly can be gotten via the VS-SDK.

var vsProject = project.Object as VSLangProj.VSProject;
var assemblyPath = vsProject.References.Item(0).Path;

ModuleDefinition module = Mono.Cecil.ModuleDefinition.ReadModule(assemblyPath);
foreach (TypeDefinition type in module.Types)
{
    var isAbstract = type.IsAbstract;
}



回答2:


You can do this with reflection. Use the GetType() function to get information about a type.

To check if a type is abstract you can do the following:

var someString = "bla";
var typeInfo = someString.GetType();
var isAbstract = typeInfo.IsAbstract;

If you don't have a variable of your desired type, you can do the following:

var typeInfo = (typeof(String));
var isAbstract = typeInfo.IsAbstract;

To check if a type is internal is a little bit . Check out this answere:

This is a classic issue. From MSDN:

The C# keywords protected and internal have no meaning in IL and are not used in the Reflection APIs. The corresponding terms in IL are Family and Assembly. To identify an internal method using Reflection, use the IsAssembly property. To identify a protected internal method, use the IsFamilyOrAssembly.

Reflection does not expose a way on Type check if it is internal, protected or protected internal.



来源:https://stackoverflow.com/questions/60737596/visual-studio-sdk-get-type-modifier-information-is-type-abstract-or-internal

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!