Code:
/ FX-1434 / FX-1434 / 1.0 / untmp / whidbey / REDBITS / ndp / fx / src / CompMod / System / CodeDOM / CodeTypeReference.cs / 1 / CodeTypeReference.cs
//------------------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//-----------------------------------------------------------------------------
namespace System.CodeDom {
using System.Diagnostics;
using System;
using Microsoft.Win32;
using System.Collections;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.Globalization;
[
ComVisible(true),
Serializable,
FlagsAttribute
]
public enum CodeTypeReferenceOptions {
GlobalReference = 0x00000001,
GenericTypeParameter = 0x00000002
}
///
///
/// Represents a Type
///
///
[
ClassInterface(ClassInterfaceType.AutoDispatch),
ComVisible(true),
Serializable,
]
public class CodeTypeReference : CodeObject {
private string baseType;
[OptionalField]
private bool isInterface;
private int arrayRank;
private CodeTypeReference arrayElementType;
[OptionalField]
private CodeTypeReferenceCollection typeArguments;
[OptionalField]
private CodeTypeReferenceOptions referenceOptions;
[OptionalField]
private bool needsFixup = false;
public CodeTypeReference() {
baseType = string.Empty;
this.arrayRank = 0;
this.arrayElementType = null;
}
public CodeTypeReference(Type type) {
if (type == null)
throw new ArgumentNullException("type");
if (type.IsArray) {
this.arrayRank = type.GetArrayRank();
this.arrayElementType = new CodeTypeReference(type.GetElementType());
this.baseType = null;
} else {
Initialize(type.FullName);
this.arrayRank = 0;
this.arrayElementType = null;
}
this.isInterface = type.IsInterface;
}
public CodeTypeReference (Type type, CodeTypeReferenceOptions codeTypeReferenceOption) : this(type) {
referenceOptions = codeTypeReferenceOption;
}
public CodeTypeReference (String typeName, CodeTypeReferenceOptions codeTypeReferenceOption): this(typeName) {
referenceOptions = codeTypeReferenceOption;
}
///
/// [To be supplied.]
///
// We support the reflection format for generice type name.
// The format is like:
//
public CodeTypeReference(string typeName) {
Initialize(typeName);
}
private void Initialize(string typeName) {
if (typeName == null || typeName.Length == 0) {
typeName = typeof(void).FullName;
this.baseType = typeName;
this.arrayRank = 0;
this.arrayElementType = null;
return;
}
typeName = RipOffAssemblyInformationFromTypeName(typeName);
int end = typeName.Length -1;
int current = end;
needsFixup = true; // default to true, and if we find arity or generic type args, we'll clear the flag.
// Scan the entire string for valid array tails and store ranks for array tails
// we found in a queue.
Queue q = new Queue();
while(current >= 0) {
int rank = 1;
if( typeName[current--] == ']') {
while(current >=0 && typeName[current] == ',') {
rank++;
current--;
}
if( current>=0 && typeName[current] == '[') { // found a valid array tail
q.Enqueue(rank);
current--;
end = current;
continue;
}
}
break;
}
// Try find generic type arguments
current = end;
ArrayList typeArgumentList = new ArrayList();
Stack subTypeNames = new Stack();
if( current > 0 && typeName[current--] == ']') {
needsFixup = false;
int unmatchedRightBrackets = 1;
int subTypeNameEndIndex = end;
// Try find the matching '[', if we can't find it, we will not try to parse the string
while(current >= 0) {
if( typeName[current] == '[' ) {
// break if we found matched brackets
if( --unmatchedRightBrackets == 0) break;
}
else if( typeName[current] == ']' ) {
++unmatchedRightBrackets;
}
else if( typeName[current] == ',' && unmatchedRightBrackets == 1) {
//
// Type name can contain nested generic types. Following is an example:
// System.Collections.Generic.Dictionary`2[[System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],
// [System.Collections.Generic.List`1[[System.Int32, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]],
// mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]
//
// Spliltting by ',' won't work. We need to do first-level split by ','.
//
if( current + 1 < subTypeNameEndIndex) {
subTypeNames.Push(typeName.Substring(current+1 , subTypeNameEndIndex - current - 1));
}
subTypeNameEndIndex = current;
}
--current;
}
if( current > 0 && (end - current - 1) > 0) {
// push the last generic type argument name if there is any
if( current + 1 < subTypeNameEndIndex) {
subTypeNames.Push(typeName.Substring(current+1 , subTypeNameEndIndex - current - 1));
}
// we found matched brackets and the brackets contains some characters.
while( subTypeNames.Count > 0) {
String name = RipOffAssemblyInformationFromTypeName((string)subTypeNames.Pop());
typeArgumentList.Add(new CodeTypeReference(name));
}
end = current - 1;
}
}
if( end < 0) { // this can happen if we have some string like "[...]"
this.baseType = typeName;
return;
}
if (q.Count > 0 ) {
CodeTypeReference type = new CodeTypeReference(typeName.Substring(0, end + 1));
for(int i = 0; i < typeArgumentList.Count; i++) {
type.TypeArguments.Add((CodeTypeReference)typeArgumentList[i]);
}
while( q.Count > 1) {
type = new CodeTypeReference( type, (int)q.Dequeue());
}
// we don't need to create a new CodeTypeReference for the last one.
Debug.Assert(q.Count == 1 , "We should have one and only one in the rank queue.");
this.baseType = null;
this.arrayRank = (int)q.Dequeue();
this.arrayElementType = type;
}
else if( typeArgumentList.Count > 0 ) {
for( int i = 0; i < typeArgumentList.Count; i++) {
TypeArguments.Add((CodeTypeReference)typeArgumentList[i]);
}
this.baseType = typeName.Substring(0, end + 1);
}
else{
this.baseType = typeName;
}
// Now see if we have some arity. baseType could be null if this is an array type.
if (baseType != null && baseType.IndexOf('`') != -1)
needsFixup = false;
}
public CodeTypeReference(string typeName, params CodeTypeReference[] typeArguments) : this(typeName){
if( typeArguments != null && typeArguments.Length > 0) {
TypeArguments.AddRange(typeArguments);
}
}
public CodeTypeReference(CodeTypeParameter typeParameter):
this( (typeParameter == null) ? (string)null : typeParameter.Name) {
referenceOptions = CodeTypeReferenceOptions.GenericTypeParameter;
}
///
/// [To be supplied.]
///
public CodeTypeReference(string baseType, int rank) {
this.baseType = null;
this.arrayRank = rank;
this.arrayElementType = new CodeTypeReference(baseType);
}
///
/// [To be supplied.]
///
public CodeTypeReference(CodeTypeReference arrayType, int rank) {
this.baseType = null;
this.arrayRank = rank;
this.arrayElementType = arrayType;
}
///
/// [To be supplied.]
///
public CodeTypeReference ArrayElementType {
get {
return arrayElementType;
}
set {
arrayElementType = value;
}
}
///
/// [To be supplied.]
///
public int ArrayRank {
get {
return arrayRank;
}
set {
arrayRank = value;
}
}
///
/// [To be supplied.]
///
public string BaseType {
get {
if (arrayRank > 0 && arrayElementType != null) {
return arrayElementType.BaseType;
}
if (String.IsNullOrEmpty(baseType))
return string.Empty;
string returnType = baseType;
if (needsFixup && TypeArguments.Count > 0)
returnType = returnType + '`' + TypeArguments.Count.ToString(CultureInfo.InvariantCulture);
return returnType;
}
set {
baseType = value;
Initialize(baseType);
}
}
[System.Runtime.InteropServices.ComVisible(false)]
public CodeTypeReferenceOptions Options {
get { return referenceOptions;}
set { referenceOptions = value;}
}
[System.Runtime.InteropServices.ComVisible(false)]
public CodeTypeReferenceCollection TypeArguments{
get {
if (arrayRank > 0 && arrayElementType != null) {
return arrayElementType.TypeArguments;
}
if( typeArguments == null) {
typeArguments = new CodeTypeReferenceCollection();
}
return typeArguments;
}
}
internal bool IsInterface {
get {
// Note that this only works correctly if the Type ctor was used. Otherwise, it's always false.
return this.isInterface;
}
}
//
// The string for generic type argument might contain assembly information and square bracket pair.
// There might be leading spaces in front the type name.
// Following function will rip off assembly information and brackets
// Following is an example:
// " [System.Collections.Generic.List[[System.String, mscorlib, Version=2.0.0.0, Culture=neutral,
// PublicKeyToken=b77a5c561934e089]], mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]"
//
private string RipOffAssemblyInformationFromTypeName(string typeName) {
int start = 0;
int end = typeName.Length - 1;
string result = typeName;
// skip white space in the beginning
while( start < typeName.Length && Char.IsWhiteSpace(typeName[start])) start++;
while( end >= 0 && Char.IsWhiteSpace(typeName[end])) end--;
if(start < end) {
if (typeName[start] =='[' && typeName[end] == ']') {
start++;
end--;
}
// if we still have a ] at the end, there's no assembly info.
if (typeName[end] != ']') {
int commaCount = 0;
for(int index = end; index >= start; index--) {
if( typeName[index] == ',') {
commaCount++;
if( commaCount == 4) {
result = typeName.Substring( start, index - start);
break;
}
}
}
}
}
return result;
}
}
}
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- XamlPathDataSerializer.cs
- SafeMILHandle.cs
- EtwTrackingBehaviorElement.cs
- Msec.cs
- QuaternionAnimationUsingKeyFrames.cs
- SettingsBindableAttribute.cs
- InstanceDescriptor.cs
- RequiredAttributeAttribute.cs
- WebPartConnection.cs
- ToolboxCategory.cs
- ContextBase.cs
- BooleanKeyFrameCollection.cs
- InputChannelAcceptor.cs
- MachineSettingsSection.cs
- CatalogZone.cs
- StrokeNodeData.cs
- TcpClientSocketManager.cs
- Track.cs
- ParsedAttributeCollection.cs
- HtmlTextArea.cs
- Internal.cs
- HttpRuntime.cs
- ConnectionPoolRegistry.cs
- DebugTraceHelper.cs
- MgmtConfigurationRecord.cs
- Evidence.cs
- HtmlInputImage.cs
- ImportCatalogPart.cs
- ExtendedPropertyInfo.cs
- DPCustomTypeDescriptor.cs
- ParamArrayAttribute.cs
- MergablePropertyAttribute.cs
- StyleCollection.cs
- SmtpDigestAuthenticationModule.cs
- GridViewCancelEditEventArgs.cs
- PassportAuthenticationModule.cs
- TextTreeNode.cs
- CookielessData.cs
- ToolStripControlHost.cs
- CacheEntry.cs
- DesignerFrame.cs
- BookmarkScopeInfo.cs
- QueryExecutionOption.cs
- LineBreakRecord.cs
- RadioButtonBaseAdapter.cs
- DataGridViewAutoSizeColumnModeEventArgs.cs
- PeerDuplexChannelListener.cs
- MultiPropertyDescriptorGridEntry.cs
- ApplicationBuildProvider.cs
- BitVector32.cs
- ApplicationServiceHelper.cs
- StructuralObject.cs
- WindowsIdentity.cs
- TTSEngineProxy.cs
- OneToOneMappingSerializer.cs
- AccessedThroughPropertyAttribute.cs
- ExtendedProperty.cs
- PathSegment.cs
- TableRow.cs
- EmbossBitmapEffect.cs
- XDRSchema.cs
- TraceRecord.cs
- Schema.cs
- UriParserTemplates.cs
- ValidationResult.cs
- BindableTemplateBuilder.cs
- SynchronousChannel.cs
- ResizingMessageFilter.cs
- DesignerResources.cs
- UserControl.cs
- StackBuilderSink.cs
- TargetControlTypeCache.cs
- VBCodeProvider.cs
- LinqDataSourceView.cs
- WorkflowDispatchContext.cs
- NaturalLanguageHyphenator.cs
- StringSorter.cs
- ZipIOLocalFileBlock.cs
- SchemaElementDecl.cs
- StringAttributeCollection.cs
- Polyline.cs
- RuntimeHelpers.cs
- PropertySet.cs
- SoapCodeExporter.cs
- BoolExpr.cs
- TreeNodeCollection.cs
- LogLogRecordEnumerator.cs
- UITypeEditor.cs
- EventLogLink.cs
- DataGridViewCellStyle.cs
- DesignerCategoryAttribute.cs
- TagElement.cs
- ImageSource.cs
- ContractAdapter.cs
- XmlSchemaValidationException.cs
- EnumUnknown.cs
- Substitution.cs
- SettingsPropertyWrongTypeException.cs
- DiagnosticsConfigurationHandler.cs
- SerializableAttribute.cs