Чтобы посмотреть какие методы, свойства и события предоставляет класс нужно:
1) Создать экземпляр класса и в IDE получить все в выпадающем списке.
2) Декомпилировать файл. К счастью, .NET проектами это очень легко проделывается.
3) Прочитать всю нужную информацию о классе с помощью Reflection.
Первый и второй вариант пройден и не считаю нужным их описывать, а вот Reflection для меня является чем-то новым, с чем я попробовал слегка разобраться.
Reflection позволяет прочитать список методов, свойств и событий класса. Далее для каждого метода мы можем получить все его перегрузки (overload) с параметрами и их типами, а для свойств мы может прочитать их типы.
Отправной точкой является тип класса (Type type), именно он содержит методы GetMember[s], GetProperty[ies], GetMethod[s], GetEvent[s] и прочие подобные. Перечисленные методы возвращают экземпляры или списки экземпляров классов MemberInfo, PropertyInfo, MethodInfo и EventInfo, содержащие подробную информацию по различным типам членов класса.
Дополнительно экземпляр MethodInfo (класс с описанием метода) имеет метод Invoke для его вызова с параметрами.
Ниже рассмотрим пример кода с комментариями:
Дополнительно экземпляр MethodInfo (класс с описанием метода) имеет метод Invoke для его вызова с параметрами.
Ниже рассмотрим пример кода с комментариями:
Type type;
String str;
// находим нужный исследуемый элемент управления на форме
Control refs = this.CardControl.Controls.Find("МоиСсылки", true)[0];
// и получаем его тип
type = refs.GetType();
ArrayList members = new ArrayList();
str = "";
// перебираем все члены класса
foreach (MemberInfo imember in type.GetMembers())
{
MethodInfo imethod = null;
// проверка на метод
if (imember is MethodInfo)
{
imethod = (MethodInfo)imember;
if (imethod != null)
{
// методы дополнительно фильтруем
if (imethod.IsAbstract || imethod.IsConstructor || imethod.IsPrivate || imethod.IsVirtual || imethod.IsSpecialName) continue;
}
}
// собираем только для одного нужного нам класса, исключая родительские
if (imember.DeclaringType.Name != "ReferenceListView") continue;
// соберем все методы, свойства и события в список
members.Add(imember);
// собираем информацию по членам класса в строку для дальнейшего вывода
str += imember.Name + " (" + imember.MemberType.ToString() + ")" + "\n";
}
MessageBox.Show(str);
// Поиск метода. В данном случае указываем дополнительные параметры поиска (типы параметров функции), так как нужный метод имеет две перегрузки (overload).
MethodInfo createCard3 = type.GetMethod("CreateCard", new Type[] { typeof(LinksLinkType), typeof(Guid), typeof(KindsCardKind) });\
str = "";
foreach (ParameterInfo pi in createCard3.GetParameters())
{
// собираем информацию по параметрам метода в строку для дальнейшего вывода
str += pi.ToString() + "\n";
}
MessageBox.Show(str);
// получаем доступные типы ссылок
PropertyInfo alt_prop = type.GetProperty("AllowedLinkTypes");
MessageBox.Show(alt_prop.ToString());
List<LinksLinkType> alts = (List<LinksLinkType>)alt_prop.GetValue(refs, new Object[] {});
// берем первый попавшийся тип ссылок
LinksLinkType llt = alts[0];
// выбираем GUID
Guid guid = this.CardData.Type.Id;
// выбираем вид карточки
KindsCardKind kck = this.CardControl.ObjectContext.GetObject<KindsCardKind>(new Guid("4ECE3759-A547-48FE-A54C-569C590F0BCA"));
// задаем массив параметров для метода
object[] ps = new Object[] { llt, guid, kck };
// вызываем полученный выше метод с параметрами
createCard3.Invoke(refs, ps);
Где-то такая функциональность может быть полезна. Например, в тех случаях, когда мы заранее не знаем с каким классом нам придется работать и нужно написать универсальный код. Но для изучения возможностей библиотеки классов, все же считаю более удобным вариантом - декомпиляцию.
Комментариев нет:
Отправить комментарий