Re: Type.Guid
От: Sinix  
Дата: 07.04.15 06:21
Оценка: 46 (3) +1
Здравствуйте, Fortnum, Вы писали:


F>Куда он смотрит, при генерировании значения сабжа? Или кеширует где-то как-то однажды сгенерированные? Но тогда, все равно, кеш к чему-то привязываться должен...

http://ayende.com/blog/3095/system-type-guid-stability

В общем случае Type.GUID заточен под получение значения из GuidAttribute, поведение в случае, если тип не размечен GuidAttribute недокументировано.
Использовать можно, только если хочется походить по граблям типа таких.

Если хочется усложнить задачу, можно завязаться на текущую реализацию (подсмотреть можно в CoreCLR):
  код
    if (*pGuid == GUID_NULL && bGenerateIfNotFound)
    {
        // For interfaces, concatenate the signatures of the methods and fields.
        if (!IsNilToken(GetCl()) && IsInterface())
        {
            // Retrieve the stringized interface definition.
            cbCur = GetStringizedItfDef(TypeHandle(this), rName);

            // Pad up to a whole WCHAR.
            if (cbCur % sizeof(WCHAR))
            {
                SIZE_T cbDelta = sizeof(WCHAR) - (cbCur % sizeof(WCHAR));
                rName.ReSizeThrows(cbCur + cbDelta);
                memset(rName.Ptr() + cbCur, 0, cbDelta);
                cbCur += cbDelta;
            }

            // Point to the new buffer.
            cchName = cbCur / sizeof(WCHAR);
            szName = reinterpret_cast<LPWSTR>(rName.Ptr());
        }
        else
        {
            // Get the name of the class.
            DefineFullyQualifiedNameForClassW();
            szName = GetFullyQualifiedNameForClassNestedAwareW(this);
            if (szName == NULL)
                return;
            cchName = wcslen(szName);

            // Enlarge buffer for class name.
            cbCur = cchName * sizeof(WCHAR);
            rName.ReSizeThrows(cbCur + sizeof(WCHAR));
            wcscpy_s(reinterpret_cast<LPWSTR>(rName.Ptr()), cchName + 1, szName);

            // Add the assembly guid string to the class name.
            ULONG cbCurOUT = (ULONG)cbCur;
            IfFailThrow(GetStringizedTypeLibGuidForAssembly(GetAssembly(), rName, (ULONG)cbCur, &cbCurOUT));
            cbCur = (SIZE_T) cbCurOUT;

            // Pad to a whole WCHAR.
            if (cbCur % sizeof(WCHAR))
            {
                rName.ReSizeThrows(cbCur + sizeof(WCHAR)-(cbCur%sizeof(WCHAR)));
                while (cbCur % sizeof(WCHAR))
                    rName[cbCur++] = 0;
            }

            // Point to the new buffer.
            szName = reinterpret_cast<LPWSTR>(rName.Ptr());
            cchName = cbCur / sizeof(WCHAR);
            // Dont' want to have to pad.
            _ASSERTE((sizeof(GUID) % sizeof(WCHAR)) == 0);
        }

        // Generate guid from name.
        CorGuidFromNameW(pGuid, szName, cchName);

        // Remeber we generated the guid from the type name.
        bGenerated = TRUE;
    }


А чтоб было совсем весело — не забываем про WinRT (цитата из того же кода):

//==========================================================================================
// Returns the GUID of this MethodTable.
// If metadata does not specify GUID for the type, GUID_NULL is returned (if bGenerateIfNotFound
// is FALSE) or a GUID is auto-generated on the fly from the name and members of the type
// (bGenerateIfNotFound is TRUE).
//
// Redirected WinRT types may have two GUIDs, the "classic" one which matches the return value
// of Type.Guid, and the new one which is the GUID of the WinRT type to which it is redirected.
// The bClassic parameter controls which one is returned from this method. Note that the parameter
// is ignored for genuine WinRT types, i.e. types loaded from .winmd files, those always return
// the new GUID.
//


Вы всё ещё хотите использовать Type.GUID?

P.S. Ну и чтобы было понятно, почему код взят из methodtable.cpp — тынц на суровую правду жизни от Андрея Акиньшина (не проходим мимо, подписываемся на блог).
Отредактировано 07.04.2015 6:24 Sinix . Предыдущая версия .
Type.Guid
От: Fortnum  
Дата: 07.04.15 02:28
Оценка:
Чего такого надо обнулить и где, чтобы конкретно у статического класса в примитивном Console Application хотя бы просто сменился сабж. Переименовываю класс, guid типа меняется. Закрываю проект, удаляю папки bin+obj. Открываю проект снова, переименовываю класс обратно... сабж тот же, что был в начале Никак изменить его не удается.

class Program
{
    static void Main()
    {
        var guid = typeof(Program).GUID;
    }
}


Но если новый проект создать, и туда 1-к-1 все скопипастить из первого проекта, guid у класса уже другой будет. То есть guid не просто к полному имени типа привязывается. [assembly: GuidAttribute()] одним и тем же делал — не помогает. Куда он смотрит, при генерировании значения сабжа? Или кеширует где-то как-то однажды сгенерированные? Но тогда, все равно, кеш к чему-то привязываться должен...
Re: Type.Guid
От: IT Россия linq2db.com
Дата: 07.04.15 03:13
Оценка:
Здравствуйте, Fortnum, Вы писали:

F>Чего такого надо обнулить и где, чтобы конкретно у статического класса в примитивном Console Application хотя бы просто сменился сабж. Переименовываю класс, guid типа меняется. Закрываю проект, удаляю папки bin+obj. Открываю проект снова, переименовываю класс обратно... сабж тот же, что был в начале Никак изменить его не удается.


В файле проекта гуиды смотрел?
Если нам не помогут, то мы тоже никого не пощадим.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.