转换" C#友好型"命名为实际类型:" INT" = GT; typeof运算(INT) [英] Convert "C# friendly type" name to actual type: "int" => typeof(int)

查看:178
本文介绍了转换" C#友好型"命名为实际类型:" INT" = GT; 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 + ")");
        }
    }
}

这篇关于转换&QUOT; C#友好型&QUOT;命名为实际类型:&QUOT; INT&QUOT; = GT; typeof运算(INT)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆