GetType()。ToString()返回对象的全名。我想要您通常用于实例化该对象的名称,即int而不是Int32。有没有办法做到这一点?
答案 0 :(得分:2)
C#具有许多“类型”,它们实际上是.NET CLR Type
的关键字别名。在这种情况下,int
是System.Int32
的C#别名,但是其他string
这样的C#类型也是如此,System.String
是Type
的别名。
这意味着当您深入思考并开始查看CLR int
对象时,您将找不到string
,// This is the set of types from the C# keyword list.
static Dictionary<Type, string> _typeAlias = new Dictionary<Type, string>
{
{ typeof(bool), "bool" },
{ typeof(byte), "byte" },
{ typeof(char), "char" },
{ typeof(decimal), "decimal" },
{ typeof(double), "double" },
{ typeof(float), "float" },
{ typeof(int), "int" },
{ typeof(long), "long" },
{ typeof(object), "object" },
{ typeof(sbyte), "sbyte" },
{ typeof(short), "short" },
{ typeof(string), "string" },
{ typeof(uint), "uint" },
{ typeof(ulong), "ulong" },
// Yes, this is an odd one. Technically it's a type though.
{ typeof(void), "void" }
};
static string TypeNameOrAlias(Type type)
{
// Lookup alias for type
if (_typeAlias.TryGetValue(type, out string alias))
return alias;
// Default to CLR type name
return type.Name;
}
或任何其他C#类型别名因为.NET和CLR不了解它们……也不应该。
如果要从CLR类型转换为C#别名,则必须自己通过查找来完成。像这样:
Nullable
对于可以正常工作的简单类型。泛型,数组和Nullable
需要更多的工作。数组和static string TypeNameOrAlias(Type type)
{
// Handle nullable value types
var nullbase = Nullable.GetUnderlyingType(type);
if (nullbase != null)
return TypeNameOrAlias(nullbase) + "?";
// Handle arrays
if (type.BaseType == typeof(System.Array))
return TypeNameOrAlias(type.GetElementType()) + "[]";
// Lookup alias for type
if (_typeAlias.TryGetValue(type, out string alias))
return alias;
// Default to CLR type name
return type.Name;
}
值的递归处理如下:
Console.WriteLine(TypeNameOrAlias(typeof(int?[][])));
这将处理以下内容:
TypeNameOrAlias
如果需要泛型,则基本上是相同的过程。扫描通用参数列表,并在整个过程中递归运行类型。
在嵌套类型上运行public class Outer
{
public class Inner
{
}
}
// TypeNameOrAlias(typeof(Outer.Inner)) == "Inner"
时,结果只是特定类型的名称,而不是您需要指定的完整路径,以便从声明它的类型之外使用它:
static string GetTypeName(Type type)
{
string name = TypeNameOrAlias(type);
if (type.DeclaringType is Type dec)
{
return $"{GetTypeName(dec)}.{name}";
}
return name;
}
// GetTypeName(typeof(Outer.Inner)) == "Outer.Inner"
这可以解决问题:
List<int>
.NET类型系统中的泛型很有趣。处理Dictionary<int, string>
或TypeNameOrAlias
之类的东西相对容易。将其插入 // Handle generic types
if (type.IsGenericType)
{
string name = type.Name.Split('`').FirstOrDefault();
IEnumerable<string> parms =
type.GetGenericArguments()
.Select(a => type.IsConstructedGenericType ? TypeNameOrAlias(a) : a.Name);
return $"{name}<{string.Join(",", parms)}>";
}
的顶部:
TypeNameOrAlias(typeof(Dictionary<int, string>))
现在,对于诸如TypeNameOrAlias(typeof(Dictionary<,>))
之类的东西,您将获得正确的结果。它还处理通用类型定义:Dictionary<TKey,TValue>
将返回GetTypeName(typeof(Dictionary<int, string>.KeyCollection))
。
当您将类嵌套在泛型中时,会遇到困难的地方。尝试vector
以获得有趣的结果。
答案 1 :(得分:1)
GetType().ToString().FromDotNetTypeToCSharpType();
使用下面的扩展方法。对于以下模板,我使用以下Microsoft参考提出了类似的建议:
https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/built-in-types-table
(可选)可以将布尔类型是否可为null传递给快捷方式可为null的语法。
/// <summary>Converts a .Net type name to a C# type name. It will remove the "System." namespace, if present,</summary>
public static string FromDotNetTypeToCSharpType(this string dotNetTypeName, bool isNull = false)
{
string cstype = "";
string nullable = isNull ? "?" : "";
string prefix = "System.";
string typeName = dotNetTypeName.StartsWith(prefix) ? dotNetTypeName.Remove(0, prefix.Length) : dotNetTypeName;
switch (typeName)
{
case "Boolean": cstype = "bool"; break;
case "Byte": cstype = "byte"; break;
case "SByte": cstype = "sbyte"; break;
case "Char": cstype = "char"; break;
case "Decimal": cstype = "decimal"; break;
case "Double": cstype = "double"; break;
case "Single": cstype = "float"; break;
case "Int32": cstype = "int"; break;
case "UInt32": cstype = "uint"; break;
case "Int64": cstype = "long"; break;
case "UInt64": cstype = "ulong"; break;
case "Object": cstype = "object"; break;
case "Int16": cstype = "short"; break;
case "UInt16": cstype = "ushort"; break;
case "String": cstype = "string"; break;
default: cstype = typeName; break; // do nothing
}
return $"{cstype}{nullable}";
}
答案 2 :(得分:-1)
如果我在阅读您的要求和理解。我假设它返回的是类似System.String
的东西,而不仅仅是String
。因此,有一种方法可以做到这一点。
string someString = "Some String Value";
//This is one quick and dirty way of mapping your returned value.
someString = someString.GetType().ToString().Substring(7);
Console.WriteLine("The variable type is {0}", someString);
如果想要“通用”选项,则基本上想要执行类似的操作。这应该做您想要的。但是请记住,如果它返回类似Int32的内容,那将是它的样子,而不仅仅是“ Int”。
//Alternatively you can just do something like this.
Console.WriteLine(someString.GetType().Name); //Returns just "String"
要进行映射,只需使用条件和变量进行重新分配。
//Your mapping would be done with this.
if (someString.GetType().Name.ToUpper() == "INT32")
{
someString = "Int";
}
else if (someString.GetType().Name.ToUpper() == "STRING")
{
someString = "String";
}