转换" C#友好型"命名为实际类型:" INT" = GT; typeof运算(INT) [英] Convert "C# friendly type" name to actual type: "int" => typeof(int)
问题描述
我希望得到一个的System.Type
给出的 字符串
的一个指定(原始)类型的的 C#友好名称的,基本的方式,C#编译器读取C#源代码时一样。
我觉得形容的最好方式我后是在单元测试的形式。
我的希望是一个通用的技术存在可以使所有的断言下方通过,而不是试图硬编码特殊情况下的特殊C#的名字。
键入GetFriendlyType(字符串的typeName){... ?? ... }
无效测试(){
//用流利的断言
GetFriendlyType(布尔)。应()为(typeof运算(布尔))。
GetFriendlyType(INT)。应()为(typeof运算(INT))。
//正确,技术上没有基本类型......(滚眼)
GetFriendlyType(字符串)。应()为(typeof运算(字符串))。
//很好,我放弃了!
//我想所有的C#类型别名工作,不只是原语
GetFriendlyType(无效)。应()为(typeof运算(无效))。
GetFriendlyType(十进制)。应()为(typeof运算(十进制))。
//加分点:拿到全类型指定的CLR类型的
GetFriendlyName(System.Activator)。应()为(typeof运算(System.Activator));
//埃里克利珀!
//不埃里克? http://stackoverflow.com/a/4369889/11545
GetFriendlyName(INT [])。应()为(typeof运算(INT []))。
GetFriendlyName(INT [,])。应()为(typeof运算(INT [,]));
//白费口舌
GetFriendlyName(INT [] [] [] [] [] [])。应()。要(typeof运算(INT [,] [, ] [] [] [] []));
}
我试了一下,到目前为止:
这问题是我的一个老问题的询问如何从获得友好名称一种。
在这个问题的答案是:使用 CSharpCodeProvider
使用(VAR提供商=新CSharpCodeProvider())
{
变种typeRef =新CodeTypeReference(typeof运算(INT));
串的friendlyName = provider.GetTypeOutput(typeRef);
}
我无法弄清楚如何(如果可能的话),这样做的周围的其他方式,并从 CodeTypeReference
(它也有一个构造函数,它接受一个字符串
)<实际的C#类型/ p>
VAR typeRef =新CodeTypeReference(typeof运算(INT));
下面是一个方法,通过使用做到这一点的罗斯林:
使用系统;
使用System.Linq的;
使用Roslyn.Scripting.CSharp;
命名空间ConsoleApplication
{
类节目
{
静态无效的主要(字串[] args)
{
控制台。的WriteLine(的GetType(INT [] [] [] [] [] []));
Console.WriteLine(的GetType(激活));
Console.WriteLine(的GetType(列出< INT [] [] [] [] [] []>中));
}
私有静态类型的GetType(字符串型)
{
变种引擎=新的ScriptEngine();
新的[] {系统}
.ToList()的ForEach(R = GT; engine.AddReference(R));
新的[] {系统,System.Collections.Generic}
.ToList()的ForEach(NS => engine.ImportNamespace(NS));
返回引擎
.CreateSession()
.Execute<类型和GT(typeof运算(+类型+));
}
}
}
I want to get a System.Type
given a string
that specifies a (primitive) type's C# friendly name, basically the way the C# compiler does when reading C# source code.
I feel the best way to describe what I'm after is in the form of an unit-test.
My hope is that a general technique exists that can make all the below assertions pass, rather than try to hard-code special cases for special C# names.
Type GetFriendlyType(string typeName){ ...??... }
void Test(){
// using fluent assertions
GetFriendlyType( "bool" ).Should().Be( typeof(bool) );
GetFriendlyType( "int" ).Should().Be( typeof(int) );
// ok, technically not a primitive type... (rolls eyes)
GetFriendlyType( "string" ).Should().Be( typeof(string) );
// fine, I give up!
// I want all C# type-aliases to work, not just for primitives
GetFriendlyType( "void" ).Should().Be( typeof(void) );
GetFriendlyType( "decimal" ).Should().Be( typeof(decimal) );
//Bonus points: get type of fully-specified CLR types
GetFriendlyName( "System.Activator" ).Should().Be(typeof(System.Activator));
//Hi, Eric Lippert!
// Not Eric? http://stackoverflow.com/a/4369889/11545
GetFriendlyName( "int[]" ).Should().Be( typeof(int[]) );
GetFriendlyName( "int[,]" ).Should().Be( typeof(int[,]) );
//beating a dead horse
GetFriendlyName( "int[,][,][][,][][]" ).Should().Be( typeof(int[,][,][][,][][]) );
}
What I tried so far:
This question is the complement of an older question of mine asking how to get the "friendly name" from a type.
The answer to that question is: use CSharpCodeProvider
using (var provider = new CSharpCodeProvider())
{
var typeRef = new CodeTypeReference(typeof(int));
string friendlyName = provider.GetTypeOutput(typeRef);
}
I can't figure out how (or if possible) to do it the other way around and get the actual C# type from the CodeTypeReference
(it also has a ctor that takes a string
)
var typeRef = new CodeTypeReference(typeof(int));
Here's a way to do it by using Roslyn:
using System;
using System.Linq;
using Roslyn.Scripting.CSharp;
namespace ConsoleApplication
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine(GetType("int[,][,][][,][][]"));
Console.WriteLine(GetType("Activator"));
Console.WriteLine(GetType("List<int[,][,][][,][][]>"));
}
private static Type GetType(string type)
{
var engine = new ScriptEngine();
new[] { "System" }
.ToList().ForEach(r => engine.AddReference(r));
new[] { "System", "System.Collections.Generic" }
.ToList().ForEach(ns => engine.ImportNamespace(ns));
return engine
.CreateSession()
.Execute<Type>("typeof(" + type + ")");
}
}
}
这篇关于转换" C#友好型"命名为实际类型:" INT" = GT; typeof运算(INT)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!