简体   繁体   English

如何从文件名生成安全的类名?

[英]How can I generate a safe class name from a file name?

I'm trying to produce some dynamically compiled code with the Razor engine, and I want to name the generated classes according to their source file names to help understand where a piece of generated code comes from. 我正在尝试使用Razor引擎生成一些动态编译的代码,并且我想根据生成的类的源文件名来命名它们,以帮助理解生成的代码的来源。

For example, I would expect the file C:\\source\\Foo.cs to be compile with the name Foo . 例如,我希望文件C:\\ source \\ Foo.cs被编译为名称Foo

Given that I have the path to the source file being compiled, is there a way to generate a valid C# identifier based on the file name? 鉴于我具有要编译的源文件的路径,是否有一种方法可以基于文件名生成有效的C#标识符?

According to the C# spec, the following rules must be adhered to when creating identifiers: 根据C#规范,创建标识符时必须遵循以下规则:

  • An identifier must start with a letter or an underscore 标识符必须以字母或下划线开头
  • After the first character, it may contain numbers, letters, connectors, etc 在第一个字符之后,它可以包含数字,字母,连接符等
  • If the identifier is a keyword, it must be prepended with “@” 如果标识符是关键字,则必须在其前面加上“ @”

This helper will satisfy those conditions: 该助手将满足以下条件:

private static string GenerateClassName(string value)
{
    string className = CultureInfo.CurrentCulture.TextInfo.ToTitleCase(value);
    bool isValid = Microsoft.CSharp.CSharpCodeProvider.CreateProvider("C#").IsValidIdentifier(className);

    if (!isValid)
    { 
        // File name contains invalid chars, remove them
        Regex regex = new Regex(@"[^\p{Ll}\p{Lu}\p{Lt}\p{Lo}\p{Nd}\p{Nl}\p{Mn}\p{Mc}\p{Cf}\p{Pc}\p{Lm}]");
        className = regex.Replace(className, "");

        // Class name doesn't begin with a letter, insert an underscore
        if (!char.IsLetter(className, 0))
        {
            className = className.Insert(0, "_");
        }
    }

    return className.Replace(" ", string.Empty);
}

It first converts the file name to camel case (personal preference), it then uses IsValidIdentifier to determine if the file name is already valid for a class name. 它首先将文件名转换为驼峰大小写(个人喜好),然后使用IsValidIdentifier确定文件名是否已对类名有效。

If not, it will remove all invalid characters based on the unicode character classes . 如果不是,它将基于unicode字符类删除所有无效字符。 It then checks whether the file name starts with a letter, if it does, it prepends an _ to fix it. 然后,它检查文件名是否以字母开头,如果是,则在其前面加上_进行修复。

Finally, I remove all whitespace (even though it would still be a valid identifier with it). 最后,我删除了所有空格(即使它仍然是有效的标识符)。

First, you need to extract the File-Name, for example with: 首先,您需要提取文件名,例如:

Path.GetFileNameWithoutExtension

Then you have to follow all rules, ac#-class name has. 然后,您必须遵循ac#类名称具有的所有规则。 For example 例如

  1. Starting with a letter or _ 以字母或_开头
  2. i would remove all other characters than _ AND az AND 0-9 我会删除除_ AND az AND 0-9以外的所有其他字符

This should be all! 这应该是全部!

您是否看过密码保护区-http: //msdn.microsoft.com/zh-cn/library/ms404245( v=vs.110) .aspx

Take the path, replace the invalid characters like \\ with let's say _ and you're done. 沿着路径,用_替换\\等无效字符,就可以了。

If you prefer shorter names, you could take the path, transform it to lowercase and take a hash value. 如果您更喜欢较短的名称,则可以采用该路径,将其转换为小写并采用哈希值。

Some code sample: 一些代码示例:

var className = pathIncludingFilename.ToLowerSinceCasingIsNotRelevant().SomeHashFunctionLikeSha1OrPartOfIt() + filename.RemoveInvalidCharactersLikeWhitespace();

The result may look like this: 结果可能如下所示:

123a3b6b22foo 123a3b6b22foo

The hash should ensure unique names, the filename makes it easier to correlate. 哈希应确保唯一的名称,文件名使关联更容易。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM