Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

C# Узнать тип данных по GUID

842
24 марта 2009 года
sigmov
301 / / 16.09.2008
Задание следующее:

Имеется файл Data.txt с двоичными данными.
В каждой его строке, начиная со 2й хранится GUID и состветствующая стандартная структура NET.Framework в двоичном(!!!) виде.

Задача:
1) Определить типы структур, зранимых в файле
2) Вывести значения структур, записанных в файле.

P.S. На экзамене в файле будет более 50ти структур для каждого варианта.

Cамое главное на мой взгляд - 1. Зная первое - второе - дело техники потому как все структуры имеют пустой конструктор.

Вот как я действовал:
Код:
static void GetTypeInBinaryFile(String^ path_name)
            {
                FILE* F = fopen((char*)(void*)Marshal::StringToHGlobalAnsi(path_name),"r");
                Guid GUID;
                char c;
                while(fscanf(F,"%c",&c)>0)
                {
                    fread(&GUID,16,1,F);
                    Type^ T = Type::GetTypeFromCLSID(GUID);
                    Console::WriteLine(T);
                }
                fclose(F);
               
            }


Но все типы определились как __ComObject!
И вот как дальше - моей фантазии не хватает.

В принципе мой препод любит давать то, что невозможно, но тогда для того чтоб не делать невозможное, ему нужно доказать невозможность невозможного.

Поэтому прошу вашей помощи. Что посоветуете?
5
24 марта 2009 года
hardcase
4.5K / / 09.08.2005
Цитата: sigmov
все типы определились как __ComObject!

Правильно определились.
CLSID это идентификатор COM-объектов.

Идентификатор типа в CLR совсем другой гуид. С ходу получилось вот что:

Код:
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Threading;

namespace GuidToType {

    public class TypeGuidHelper : IDisposable {

        public TypeGuidHelper()
            : this(AppDomain.CurrentDomain) {
        }

        public TypeGuidHelper(AppDomain domain) {
            if (ReferenceEquals(domain, null))
                throw new ArgumentNullException("domain");
            this._domain = domain;
            this._type_locker = new ReaderWriterLock();
            this._types = new Dictionary<Guid, Type>();
             _domain.AssemblyLoad += CurrentDomain_AssemblyLoad;
            foreach (Assembly asmb in _domain.GetAssemblies())
                ProcessAssemblyTypes(asmb);
        }

        private AppDomain _domain;

        public AppDomain Domain {
            get {
                return _domain;
            }
        }

        private Dictionary<Guid, Type> _types;

        private ReaderWriterLock _type_locker;

        private void CurrentDomain_AssemblyLoad(object sender, AssemblyLoadEventArgs args) {
            ProcessAssemblyTypes(args.LoadedAssembly);
        }

        private void ProcessAssemblyTypes(Assembly asmb) {
            _type_locker.AcquireWriterLock(-1);
            try {
                foreach (Type type in asmb.GetTypes()) {
                    _types[type.GUID] = type;
                }
            } finally {
                _type_locker.ReleaseWriterLock();
            }
        }

        public Type this[Guid id] {
            get {
                _type_locker.AcquireReaderLock(-1);
                try {
                    return _types[id];
                } finally {
                    _type_locker.ReleaseReaderLock();
                }
            }
        }

        public bool TryGetType(Guid id, out Type type) {
            _type_locker.AcquireReaderLock(-1);
            try {
                return _types.TryGetValue(id, out type);
            } finally {
                _type_locker.ReleaseReaderLock();
            }
        }

        #region IDisposable Members

        public void Dispose() {
            _domain.AssemblyLoad -= CurrentDomain_AssemblyLoad;
        }

        #endregion
    }


    class Program {

        class NestedClass {

        }

        static void Main(string[] args) {
            using (TypeGuidHelper helper = new TypeGuidHelper()) {
                Type type;
                if (helper.TryGetType(typeof(NestedClass).GUID, out type)) {
                    Console.WriteLine(type);
                } else {
                    Console.WriteLine("Type not found");
                }
            }

            Console.ReadLine();

        }
    }
}
Создаем специальную таблицу и загоняем все типы из загруженных сборок в данном домене приложения. Этот хэлпер также добавляет обработчик загрузки сборки в домен и дописывает найденные в ней типы в таблицу.



З.Ы. А чего тему то в "Студентах" разместил? Вопрос то не самый тривиальный. :)
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог