В настоящее время я пытаюсь программно создать File.ReadAllText файл C# (.cs) и преобразовать его в объект Type, чтобы я мог получить доступ к функции Type.GetMethods() (и остальным функциям). Этот файл .cs НЕ находится в том же проекте, поэтому я не могу просто вызвать класс в самом коде.
Единственная проблема в том, что я не могу найти способ сделать это. Я пробовал следующее ниже, преобразовывая String в объект типа с помощью TypeDescriptor, но это не удалось с ошибкой.
Код:
string code = File.ReadAllText(PathToHomeControllerFile);
Type t = (Type)TypeDescriptor.GetConverter(typeof(String)).ConvertTo(code, typeof(Type));
string methods = string.Join(",", t.GetMethods().Select(p => p.Name));
Console.WriteLine(methods);
Файл, который я пытаюсь преобразовать (HomeController.cs):
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace TestApplication.Controllers
{
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
public ActionResult TestAction()
{
return View();
}
}
}
Ошибка:
'StringConverter' is unable to convert 'System.String' to 'System.Type'.
Как мне достичь своей цели?
@JonSkeet Можно ли программно скомпилировать код? Если да, то как? :)
Это возможно, но не ожидайте, что это будет однострочный. В Интернете есть лоты ресурсов по этому поводу - я предлагаю вам поискать руководство по Roslyn.
@JonSkeet Хм .. Неужели нет другого выхода? В основном мне нужна только информация о функциях (имя, тип возвращаемого значения и входные параметры, вот и все)
Так что по крайней мере вам понадобится C# парсер. Нет, это не тривиально. Возможно, вы сможете использовать Roslyn с меньшим количеством дополнительной информации, чем для полной компиляции, но это непросто.
@KevinJensenPetersen Если все, что вам нужно, это информация о методах, то не читайте в файле C# - встроите его в DLL, сгенерировать его XML-описание, а затем прочтите вместо этого XML-описание. Однако я хотел бы, чтобы вы объяснили, чего вы на самом деле пытаетесь достичь, потому что это может сработать, а может и не сработать в зависимости от ваших ограничений.
@RB. Ну, вариант использования находится в расширении VSIX, где мне нужно получить информацию обо всех контроллерах MVC, чтобы я мог создавать отчет об этой информации каждый раз, когда нажимается пользовательская кнопка расширения VSIX, поэтому встраивание ее в DLL - это своего рода вопроса.
Почему вы не можете использовать коллекцию Projects, получить коллекцию CodeModel.CodeElements для каждого проекта и проанализировать ее? Здесь - это статья MS о том, как это сделать в VB.
@NetMage Это было именно то, что мне было нужно. Я не работал и нашел ответ на Stackoverflow на основе CodeModel.CodeElements и нашел решение здесь: stackoverflow.com/questions/32791188/…





Поскольку я работал с VSIX Extensions, я мог просто использовать CodeModel.CodeElements, как указано в комментариях к исходному сообщению. Я нашел ответ от другого товарища по Stackoverflower, и это помогло.
Расширение Visual Studio получает метаданные всех классов и интерфейсов
Ну, вам нужно будет скомпилировать код - что далеко не тривиально, учитывая, что вам нужно знать, на какие другие сборки ссылаться и т. д.