public void EnsureItemStorageType(XmlQueryType xmlType, Type storageTypeDest) {
// If source type = destination type, then done
if (this.storage.ItemStorageType == storageTypeDest)
goto SetStorageType;
Debug.Assert(this.storage.ItemStorageType == typeof(XPathItem) || storageTypeDest == typeof(XPathItem),
"EnsureItemStorageType must convert to or from Item");
// If items are cached,
if (this.storage.IsCached) {
// Check for special case of IList<XPathNavigator> -> IList<XPathItem>
if (this.storage.ItemStorageType == typeof(XPathNavigator)) {
EnsureStack();
this.helper.Call(XmlILMethods.NavsToItems);
goto SetStorageType;
}
// Check for special case of IList<XPathItem> -> IList<XPathNavigator>
if (storageTypeDest == typeof(XPathNavigator)) {
EnsureStack();
this.helper.Call(XmlILMethods.ItemsToNavs);
goto SetStorageType;
}
}
// Iterate over each item, and convert each to the destination type
EnsureStackNoCache();
// If source type is Item,
if (this.storage.ItemStorageType == typeof(XPathItem)) {
// Then downcast to Navigator
if (storageTypeDest == typeof(XPathNavigator)) {
this.helper.Emit(OpCodes.Castclass, typeof(XPathNavigator));
}
else {
// Call ValueAs methods for atomic types
this.helper.CallValueAs(storageTypeDest);
}
goto SetStorageType;
}
else if (this.storage.ItemStorageType == typeof(XPathNavigator)) {
// No-op if converting from XPathNavigator to XPathItem
Debug.Assert(storageTypeDest == typeof(XPathItem), "Must be converting from XPathNavigator to XPathItem");
goto SetStorageType;
}
// Destination type must be item, so generate code to create an XmlAtomicValue
this.helper.LoadInteger(this.helper.StaticData.DeclareXmlType(xmlType));
this.helper.LoadQueryRuntime();
this.helper.Call(XmlILMethods.StorageMethods[this.storage.ItemStorageType].ToAtomicValue);
SetStorageType:
this.storage = this.storage.ToStorageType(storageTypeDest);
}
}