从输入字符串

时间:2015-10-08 09:45:30

标签: c#

我目前正在创建一个模块,它将使用C#中的Gembox.Document在word中创建合并字段。首先,我只是想说这是我给出的一项任务,所以这是一个不好的方法,这是他们想要的方式。

我有一个Windows窗体应用程序,其中有一个文本框和一个按钮。在文本框中,他们希望可以粘贴dto / model,例如:

"public class Example 
{
    public string Name { get; set; }
    public string Surname { get; set; }
    public string Cellphone { get; set; }
    public string Address { get; set; }
    public string CompanyName { get; set; }
    public DateTime CurrentDate { get; set; }  
}"

我已经有了一个逻辑,用一个方法将mergefields添加到word中,我传入一个包含所有合并字段名称的字符串[]。

问题是:我需要能够以某种方式对这个包含在文本框中写为字符串的dto / model的大字符串进行子串,以获取属性名称并将它们添加到string[],因为它们将是合并字段名称。

我希望我能够很好地解释自己。这是我的第一个问题,我不习惯用英语解释我的问题。

编辑: 指定问题:我需要从此字符串中获取属性名称并将其放入string[]

string s = @"public string Name { get; set; }
  public string Surname { get; set; }
  public string Cellphone { get; set; }
  public string Address { get; set; }
  public string CompanyName { get; set; }
  public DateTime CurrentDate { get; set; }"

3 个答案:

答案 0 :(得分:3)

我认为也许你应该解析这个文本(使用解析器不是自己的解决方案)而不是搜索语法树来查找属性名称。我想到类似的东西:

Using NRefactory for analyzing C# code

此代码返回完整的树或错误(我使用NRefactory,但您可以使用Roslyn):

var parser = new CSharpParser();
var syntaxTree = parser.Parse(programCode);

搜索属性的 syntaxTree 字段。

示例代码:

const string code = @"public class Example {
    public string Name { get; set; }
    public string Surname { get; set; }
    public string Cellphone { get; set; }
    public string Address { get; set; }
    public string CompanyName { get; set; }
    public DateTime CurrentDate { get; set; }
}";
var syntaxTree = new CSharpParser().Parse(code, "program.cs");
var listOfPropertiesNames = syntaxTree.Children
    .SelectMany(astParentNode => astParentNode.Children)
    .OfType<PropertyDeclaration>()
    .Select(astPropertyNode => astPropertyNode.Name)
    .ToList();

此代码段提取属性名称。

答案 1 :(得分:1)

您可以使用CSharpCodeProvider类将代码编译为程序集,然后使用反射来查找已编译程序集中的类型。

return gulp.src([config.html + '**/*.php','!assets','!myPhpTestFolder', '!build', '!html'])

更新: 但请记住,无法卸载在app域中加载的类型,并且在应用程序退出之前将继续占用内存。

因此,如果用户经常使用此函数,则会逐渐消耗内存。

如果这成为问题,您可以通过创建单独的应用程序域或生成另一个进程来提供此功能来解决此问题,但这是另一个问题。

答案 2 :(得分:1)

您可以创建自定义静态方法来解析文本。它的作用是从一个&#39; {&#39;到下一个索引后退并检查是否有&#39;(&#39;或&#39;)&#39; char(表示它是一个方法而不是属性,它应该跳过它)然后向后查找属性的开头。之后,它提取值,然后跳转到下一个索引{&#39; char等等:

    static string[] GetProperties(string dirty)
    {
        List<string> properties = new List<string>();
        int i = dirty.IndexOf("{ ");
        StringBuilder sb = new StringBuilder();
        int propEndIndex = -1; int i2 = -1;

        for (; i != -1; i = dirty.IndexOf("{ ", i + 1))
        {
            i2 = i - 1;

            for (; dirty[i2] == ' '; i2--) { }

            if (dirty[i2] == '(' || dirty[i2] == ')') continue;

            propEndIndex = i2 + 1;

            for (; dirty[i2] != ' '; i2--) { }                

            for (i2++; i2 < propEndIndex; i2++)
                sb.Append(dirty[i2]);                

            properties.Add(sb.ToString());
            sb.Clear();
        }

        return properties.ToArray();
    }

使用示例:

       Stopwatch sw = new Stopwatch();

        var s = @"public class Example 
                {
                   public string Name { get; set; }
                   public string Surname { get; set; }
                   public string Cellphone { get; set; }
                   public string Address { get; set; }
                   public string CompanyName { get; set; }
                   public DateTime CurrentDate { get; set; }  

                   public void MyMethod() { }
                }";

        sw.Start();

        string[] props =  GetProperties(s);

        sw.Stop();

        foreach (var item in props)
            Console.WriteLine(item);

        Console.WriteLine("\n\nMethod is executed in " + sw.ElapsedMilliseconds + " ms");

        Console.ReadKey();

输出:

Name
Surname 
CellPhone
Address
CompanyName 
CurrentDate

Method is executed in 1 ms