Здравствуйте, 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 —
тынц на суровую правду жизни от Андрея Акиньшина (не проходим мимо, подписываемся на блог).
Чего такого надо обнулить и где, чтобы конкретно у статического класса в примитивном Console Application хотя бы просто сменился сабж. Переименовываю класс, guid типа меняется. Закрываю проект, удаляю папки bin+obj. Открываю проект снова, переименовываю класс обратно... сабж тот же, что был в начале
Никак изменить его не удается.
class Program
{
static void Main()
{
var guid = typeof(Program).GUID;
}
}
Но если новый проект создать, и туда 1-к-1 все скопипастить из первого проекта, guid у класса уже другой будет. То есть guid не просто к полному имени типа привязывается. [assembly: GuidAttribute()] одним и тем же делал — не помогает. Куда он смотрит, при генерировании значения сабжа? Или кеширует где-то как-то однажды сгенерированные? Но тогда, все равно, кеш к чему-то привязываться должен...
Здравствуйте, Fortnum, Вы писали:
F>Чего такого надо обнулить и где, чтобы конкретно у статического класса в примитивном Console Application хотя бы просто сменился сабж. Переименовываю класс, guid типа меняется. Закрываю проект, удаляю папки bin+obj. Открываю проект снова, переименовываю класс обратно... сабж тот же, что был в начале Никак изменить его не удается.
В файле проекта гуиды смотрел?