我正在尝试使用CodeDOM创建扩展方法。似乎没有对它们的任何支持,并且不允许使用ExtensionAttribute
(C#内部用于标记扩展方法)。
可以使用a trick指定this
修饰符,但如何创建包含类static
,以便代码实际编译?
由于static
是C#概念,因此不会通过CodeDOM API公开。将TypeAttributes
设置为TypeAttributes.Abstract | TypeAttributes.Sealed | TypeAttributes.Public
不起作用,因为
抽象类不能密封或静态
如何使扩展方法编译?
答案 0 :(得分:6)
我很确定你在寻找:
var staticClass = new CodeTypeDeclaration("Extensions")
{
Attributes = MemberAttributes.Public|MemberAttributes.Static
};
然而,这似乎不起作用。有趣的是:
provider.Supports(GeneratorSupport.StaticConstructors);
// True
provider.Supports(GeneratorSupport.PublicStaticMembers);
// True
但是当你去输出它时,即使属性属性明显从0x00005002
变为0x00006003
,也没有变化。
Per Microsoft Connect this is not possible:
感谢您报告此事。不幸的是,看起来我们不能支持CodeDom的静态类。
原因是CodeDom的设计目标之一是与语言无关,因此可以轻松地为不同语言生成为一种语言生成的任何代码。虽然静态类经常在C#中使用,但VB不支持它们。因此,添加对静态类的支持意味着一些可以为C#编译的代码将无法编译为VB,这违背了我们的目标。
虽然我们无法就此问题采取行动,但我们请您继续提供反馈,以帮助我们改进。
肮脏的解决方法:
var type = new CodeTypeDeclaration("Extensions");
type.Attributes = MemberAttributes.Public;
type.StartDirectives.Add(
new CodeRegionDirective(CodeRegionMode.Start, "\nstatic"));
type.EndDirectives.Add(
new CodeRegionDirective(CodeRegionMode.End, String.Empty));
产地:
#region
static
public class Extensions
{
}
#endregion
哪个编译。
答案 1 :(得分:2)
稍微清理了六个变量提供的hack:将其置于静态方法中,如讨论中所述。
public static void MarkAsStaticClassWithExtensionMethods(this CodeTypeDeclaration class_)
{
class_.Attributes = MemberAttributes.Public;
class_.StartDirectives.Add(new CodeRegionDirective(
CodeRegionMode.Start, Environment.NewLine + "\tstatic"));
class_.EndDirectives.Add(new CodeRegionDirective(
CodeRegionMode.End, string.Empty));
}
答案 2 :(得分:1)
您可以获取源代码,将CodeCompileUnit
替换为class Extensions
并编译该代码,而不是直接编译static class Extensions
。
答案 3 :(得分:0)
您可以通过将代码直接转换为字符串,然后将其破解来让您的代码准确编译您的需求:
private static CodeSnippetTypeMember CreateStaticClass(CodeTypeDeclaration type)
{
var provider = CodeDomProvider.CreateProvider("CSharp");
using (var sourceWriter = new StringWriter())
using (var tabbedWriter = new IndentedTextWriter(sourceWriter, "\t"))
{
tabbedWriter.Indent = 2;
provider.GenerateCodeFromType(type, tabbedWriter, new CodeGeneratorOptions()
{
BracingStyle = "C",
IndentString = "\t"
});
return new CodeSnippetTypeMember("\t\t" + sourceWriter.ToString().Replace("public class", "public static class"));
}
}