/// <summary> /// Each XmlQueryType has multiple legal CLR representations. Ensure that all items returned by this iterator are in /// the Clr representation specified by "storageTypeDest". /// </summary> public void EnsureItemStorageType(XmlQueryType xmlType, Type storageTypeDest) { // If source type = destination type, then done if (_storage.ItemStorageType == storageTypeDest) { goto SetStorageType; } Debug.Assert(_storage.ItemStorageType == typeof(XPathItem) || storageTypeDest == typeof(XPathItem), "EnsureItemStorageType must convert to or from Item"); // If items are cached, if (_storage.IsCached) { // Check for special case of IList<XPathNavigator> -> IList<XPathItem> if (_storage.ItemStorageType == typeof(XPathNavigator)) { EnsureStack(); _helper.Call(XmlILMethods.NavsToItems); goto SetStorageType; } // Check for special case of IList<XPathItem> -> IList<XPathNavigator> if (storageTypeDest == typeof(XPathNavigator)) { EnsureStack(); _helper.Call(XmlILMethods.ItemsToNavs); goto SetStorageType; } } // Iterate over each item, and convert each to the destination type EnsureStackNoCache(); // If source type is Item, if (_storage.ItemStorageType == typeof(XPathItem)) { // Then downcast to Navigator if (storageTypeDest == typeof(XPathNavigator)) { _helper.Emit(OpCodes.Castclass, typeof(XPathNavigator)); } else { // Call ValueAs methods for atomic types _helper.CallValueAs(storageTypeDest); } goto SetStorageType; } else if (_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 _helper.LoadInteger(_helper.StaticData.DeclareXmlType(xmlType)); _helper.LoadQueryRuntime(); _helper.Call(XmlILMethods.StorageMethods[_storage.ItemStorageType].ToAtomicValue); SetStorageType: _storage = _storage.ToStorageType(storageTypeDest); }