MSDN , . , (, , Microsoft - .NET 4.0?)
public static class TypeHelpers
{
public static Type GetType(string typeName, bool throwOnError, bool ignoreCase)
{
if(string.IsNullOrEmpty(typeName))
throw new ArgumentNullException("typeName");
Type type;
if((type = Type.GetType(typeName, false, ignoreCase)) != null)
return type;
try
{
return GetTypeFromRecursive(typeName, ignoreCase);
}
catch(Exception e)
{
if(throwOnError)
throw;
}
return null;
}
#region Private Static Helper Methods
private static Type GetTypeFromRecursive(string typeName, bool ignoreCase)
{
int startIndex = typeName.IndexOf('[');
int endIndex = typeName.LastIndexOf(']');
if(startIndex == -1)
{
return TypeHelpers.GetNonGenericType(typeName, ignoreCase);
}
else
{
int cardinalityIndex = typeName.IndexOf('`', 0, startIndex);
string cardinalityString = typeName.Substring(cardinalityIndex + 1, startIndex - cardinalityIndex - 1);
int cardinality = int.Parse(cardinalityString);
string fullName = typeName.Substring(0, startIndex);
if(typeName.Length - endIndex - 1 > 0)
fullName += typeName.Substring(endIndex + 1, typeName.Length - endIndex - 1);
List<Type> list = new List<Type>();
string typeArguments = typeName.Substring(startIndex + 1, endIndex - startIndex - 1);
foreach(string item in EachAssemblyQualifiedName(typeArguments, cardinality))
{
Type typeArgument = GetTypeFromRecursive(item, ignoreCase);
list.Add(typeArgument);
}
return TypeHelpers.GetNonGenericType(fullName, ignoreCase).MakeGenericType(list.ToArray());
}
}
private static IEnumerable<string> EachAssemblyQualifiedName(string s, int count)
{
Debug.Assert(count != 0);
Debug.Assert(string.IsNullOrEmpty(s) == false);
Debug.Assert(s.Length > 2);
int startIndex = 0;
int bracketCount = 0;
while(count > 0)
{
bracketCount = 0;
for(int i = startIndex; i < s.Length; i++)
{
switch(s[i])
{
case '[':
bracketCount++;
continue;
case ']':
if(--bracketCount == 0)
{
string item = s.Substring(startIndex + 1, i - startIndex - 1);
yield return item;
startIndex = i + 2;
}
break;
default:
continue;
}
}
if(bracketCount != 0)
{
const string SR_Malformed = "The brackets are unbalanced in the string, '{0}'.";
throw new FormatException(string.Format(SR_Malformed, s));
}
count--;
}
}
private static Type GetNonGenericType(string typeName, bool ignoreCase)
{
Type type = Type.GetType(typeName, false, ignoreCase);
if(type != null)
return type;
int assemblyFullNameIndex = typeName.IndexOf(',');
if(assemblyFullNameIndex != -1)
{
string assemblyFullName = typeName.Substring(assemblyFullNameIndex + 2, typeName.Length - assemblyFullNameIndex - 2);
foreach(Assembly assembly in AppDomain.CurrentDomain.GetAssemblies())
{
if(assembly.GetName().FullName == assemblyFullName)
{
string fullName = typeName.Substring(0, assemblyFullNameIndex);
type = assembly.GetType(fullName, false, ignoreCase);
if(type != null)
return type;
}
}
}
const string SR_TypeNotFound = "The type, '{0}', was not found.";
throw new ArgumentException(string.Format(SR_TypeNotFound, typeName), "typeName");
}
#endregion
}
, MbUnit:
[Test]
public void GetType_DictionaryOfStringAndDictionaryOfInt32AndKeyValuePairOfStringAndListOfInt32()
{
Dictionary<string, Dictionary<int, KeyValuePair<string, List<int>>>> obj =
new Dictionary<string, Dictionary<int, KeyValuePair<string, List<int>>>>();
string typeName = obj.GetType().FullName;
Type type = TypeHelpers.GetType(typeName, true, false);
Assert.IsTrue(type.Equals(obj.GetType()));
}
. , Type.GetType().