这就是我想要做的。
我想写这样的 POCO 类:
[AutoExtended]
public partial class Foo {
public int Bar;
public string Baz;
}
最好在我的解决方案中的任意文件中(
[AutoExtend]
属性是我刚刚编写的用于识别兴趣类的东西)。我希望构建过程从 (a) 在我的源代码中查找这些
AutoExtend
类和 (b) 自动生成这样的扩展开始:public partial class Foo {
public static SomeType<int> Bar(Foo x) { ... };
public static SomeOtherType<string> Baz(Foo x) { ... };
}
在编译解决方案之前。
有谁知道如何最好地做到这一点?我想 Roslyn 是要走的路,但我愿意接受建议。理想情况下,我想要一个解决方案,除了
AutoExtend
属性之外,用户方面需要零额外的“管道”。(如果有人感兴趣,我正在根据带有重载运算符的 C# 类编写域特定语言,上述内容将使 DSL 使用起来更加舒适。)
最佳答案
正如评论中所建议的,T4 是非常可行的。
关于构建时的转换,您可以使用 .csproj 文件中的 <TransformOnBuild>
属性来完成。参见 this question ,特别是@Cheburek 的回答。还有更多信息 on MSDN 。
然后要使用 AutoExtend
属性定位类,您需要使用 EnvDTE 而不是反射,因为任何现有的程序集都会过时。
就像是:
<#
// get a reference to the project of this t4 template
var project = VisualStudioHelper.CurrentProject;
// get all class items from the code model
var allClasses = VisualStudioHelper.GetAllCodeElementsOfType(project.CodeModel.CodeElements, EnvDTE.vsCMElement.vsCMElementClass, false);
// iterate all classes
foreach(EnvDTE.CodeClass codeClass in allClasses)
{
// get all attributes this method is decorated with
var allAttributes = VisualStudioHelper.GetAllCodeElementsOfType(codeClass.Attributes, vsCMElement.vsCMElementAttribute, false);
// check if the SomeProject.AutoExtendedAttribute is present
if (allAttributes.OfType<EnvDTE.CodeAttribute>()
.Any(att => att.FullName == "SomeProject.AutoExtended"))
{
#>
// this class has been generated
public partial class <#= codeClass.FullName #>
{
<#
// now get all methods implemented by the class
var allFunctions = VisualStudioHelper.GetAllCodeElementsOfType(codeClass.Members, EnvDTE.vsCMElement.vsCMElementFunction, false);
foreach(EnvDTE.CodeFunction function in allFunctions)
{
#>
public static <#= function.FullName #> etc...
<#
}
#>
}
<#
}
}
}
#>
关于c# - 在 Visual Studio 中自动生成部分类的扩展,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/18653991/