【问题标题】:using CodeDom create a generic method使用 CodeDom 创建一个泛型方法
【发布时间】:2015-04-22 06:27:42
【问题描述】:

我想使用 codedom 创建一个通用方法.. 我试过这段代码

foreach (MethodInfo mhttem in sMethodName)
{
     var mth = new CodeMemberMethod();
     mth.Name = mhttem.Name;
     mth.ReturnType = new CodeTypeReference(mhttem.ReturnType.Name);
     foreach (var param in mhttem.GetParameters())
     {
         mth.Parameters.Add(new CodeParameterDeclarationExpression(param.ParameterType, param.Name)); 
     }
} 

但是在方法参数中,也显示了命名空间。 比如……

    ReminderTemplate GeTemplateById(System.Guid templateId);

我只想要

    ReminderTemplate GeTemplateById(Guid templateId);

这里 mth.Parameters.Add(new CodeParameterDeclarationExpression(param.ParameterType.Name, param.Name));

但是如果我有字符串类型的参数,它会转换为 字符串类

例如

      PendingEmail GetByEmailToSubjectBodyMsg(String emailTo, String subject, String bodyMsg);

提前致谢

【问题讨论】:

  • 我看到你已经用你的尝试更新了这个问题。不用担心String 至少与 C# 编译器的string 相同。
  • 是的,但我需要一个字符串作为数据类型
  • 我认为您将泛型方法与生成方法混淆了。第一个实际上是一个带有类型参数的方法,我在您的 GetTemplateById 方法中看不到。

标签: c# asp.net generics methods codedom


【解决方案1】:

CSharpCodeGenerator 中有一个硬编码的类型列表,将被转换为等效的 C# 类型。如果全名不是 C# 可识别的类型之一,这些扩展方法将转换类型(命名空间 + 名称)的全名,将其从命名空间中剥离。

public static class CSharpCodeDomExtensions
{
    // Taken from CSharpCodeGenerator.GetBaseTypeOutput(CodeTypeReference typeRef)
    private static readonly HashSet<string> BaseTypes = new HashSet<string>
    {
        "system.int16", "system.int32", "system.int64", 
        "system.string", "system.object", "system.boolean", "system.void", 
        "system.char", "system.byte", 
        "system.uint16", "system.uint32", "system.uint64", 
        "system.sbyte", 
        "system.single", "system.double", "system.decimal"
    };

    private static bool IsBaseType(string fullName)
    {
        // It is done in this way in CSharpCodeGenerator.GetBaseTypeOutput
        return BaseTypes.Contains(fullName.ToLower(CultureInfo.InvariantCulture).Trim());
    }

    public static string StripNameSpaces(this Type type)
    {
        string fullName = type.FullName;

        if (IsBaseType(fullName))
        {
            return fullName;
        }

        return type.Name;
    }

    public static string StripNameSpaces(this string fullName)
    {
        if (IsBaseType(fullName))
        {
            return fullName;
        }

        return fullName.Split('.').Last();
    }
}

像这样使用它:

mth.Parameters.Add(new CodeParameterDeclarationExpression(param.ParameterType.StripNamespaces(), param.Name)); 

请注意,剥离命名空间有一些缺点:您必须确保在 CodeDom 中包含“正确”的命名空间,并且您可以有多个共享同一个命名空间的类。其他问题:您无法区分OuterClass.InnerClassNamespace.OuterClass。对此无法轻松进行检查。

【讨论】:

    【解决方案2】:

    您可以使用Type 类的Name 属性来避免类型的完全限定名称。

    mth.Parameters.Add(new CodeParameterDeclarationExpression(param.ParameterType.Name, param.Name)); 
    

    【讨论】:

    • 喜欢..PendingEmail GetByEmailToSubjectBodyMsg(String emailTo, String subject, String bodyMsg);我想要........PendingEmail GetByEmailToSubjectBodyMsg(string emailTo, string subject, string bodyMsg);
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-11-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-03
    • 2021-02-18
    相关资源
    最近更新 更多