gpt4 book ai didi

.net - 有没有办法以编程方式提取接口(interface)?

转载 作者:行者123 更新时间:2023-12-03 15:13:19 25 4
gpt4 key购买 nike

假设我有一个像这样的 .NET 类:

public class Person {
public string Name { get; set; }
public int Id { get; set; }
}

Visual Studio 有一个漂亮的重构工具,称为提取接口(interface),它可以提取 IPerson接口(interface),并有 Person实现它。有没有办法从 Visual Studio 外部以编程方式做到这一点?如果不能以编程方式完成,我什至会使用 shell 脚本。

[编辑]
实际上,我最多有 50 个类,每个类都相互依赖。

反射会起作用,但它会给整个事情带来另一个皱纹。 xsd.exe 已经生成了这些类。 .因此,如果我理解正确,我需要采取的步骤是:
  • xsd.exe 生成类.
  • 即时编译类,以便我可以使用反射。
  • 反射它们,发出接口(interface),并编辑原始类以
    实现上述接口(interface)。

  • 一般来说,我赞成放弃接口(interface)并直接使用类,但由于各种原因我不能。

    最佳答案

    后来我遇到了同样的问题,找到了上面接受的解决方案,并决定在此处添加更多信息和详细信息,以了解我如何使用反射和其他功能以编程方式在源代码中生成接口(interface)。 (如果您不关心使用自定义属性标记源代码以生成代码,请跳过这第一 block 代码)

    为了灵 active ,我创建了名为 GenerateInterface 和 GenerateInterfaceMember 的自定义属性(只是我自己的创作)来标记我想要明确导出到接口(interface)的部分的类和成员(或者您可以默认导出所有公共(public)成员,无论您喜欢什么)。例如,我将这样的属性应用于 Store 类......

    [GenerateInterface(InterfaceName="IStore", NamespaceName="Com.Example.GenerationTest")]
    class Store : BusinessObject {
    string _name;

    [GenerateInterfaceMember]
    public event EventHandler handler;

    internal Store(IDomain domain, string name)
    : base(domain) {
    _name = name;
    }

    [GenerateInterfaceMember]
    public string GetSomething(int a, int b, Random r, Store s) {
    throw new NotImplementedException();
    }
    //etc...

    有关 custom Attributes see MSDN 的信息.

    代码生成的东西...

    注意:您可以在不使用上面显示的自定义属性的情况下执行以下所有操作。

    我用了 reflection迭代类型和成员。您只需要获取类中的所有公共(public)成员作为创建接口(interface)的候选对象。

    在使用反射在 System.Type 上获取 System.Reflection.PropertyInfo、.MethodInfo 等实例后,我创建了一个与语言无关的代码编译单元,并由类 System.CodeDom.CodeCompileUnit, of which MSDN has good example code - see it here. 表示.代码编译单元实例是您需要构建的,以描述您希望以独立于语言的方式生成的源代码。

    创建 CodeCompileUnit 实例后,您可以将其提供给各种 FCL 方法以满足您的需求,例如生成源代码、在内存或磁盘中发出 MSIL 代码等。为了生成源代码,我使用了 System.CodeDom.Compiler.CodeDomProvider See the MSDN sample除了下面一起破解的解决方案......

    CodeDomProvider 是特定语言的地方 - 这些语言嵌套在 Microsoft 命名空间下,例如:
    using Microsoft.CSharp; // for C#
    using Microsoft.VisualBasic; // for VB.NET

    有几种方法可以创建 CodeDomProvider 实例,例如此处的 MSDN 代码示例显示了一个静态方法“.CreateProvider”:
    CodeDomProvider provider = null;
    // snip...
    case "CSharp":
    provider = CodeDomProvider.CreateProvider("CSharp");
    break;
    case "Visual Basic":
    provider = CodeDomProvider.CreateProvider("VisualBasic");
    break;

    或者,您可以直接实例化提供程序
    Microsoft.CSharp.CSharpCodeProvider csProvider = new CSharpCodeProvider();
    Microsoft.VisualBasic.VBCodeProvider vbProvider = new VBCodeProvider();

    在提供者实例上使用方法,如 provider.GenerateCodeFromCompileUnit(..)并将您的 CodeCompileUnit 实例提供给它。此示例代码为 StringBuilder 实例生成 C# 源代码。
    // me setting up string capture for my purposes
    StringBuilder szBuilder = new StringBuilder();
    StringWriter writer = new StringWriter(szBuilder);

    // the key statement - writes c# code to StringBuilder using provider instance and compile unit instance
    csProvider.GenerateCodeFromCompileUnit(compileUnit, writer, new CodeGeneratorOptions());

    // solidifying the generated C# code into one string
    string sourceCode = szBuilder.ToString();
    // can write this string to a file, etc....

    你已经生成了源代码。

    在输出 sourceCode 字符串时,我最终得到了类似这样的东西。微软在关于自动生成的文件的评论前面加上了很好的评论——让它感觉更“正式”。
    //------------------------------------------------------------------------------
    // <auto-generated>
    // This code was generated by a tool.
    // Runtime Version:2.0.50727.4200
    //
    // Changes to this file may cause incorrect behavior and will be lost if
    // the code is regenerated.
    // </auto-generated>
    //------------------------------------------------------------------------------

    namespace Com.Example.GenerationTest {
    using System;
    using Com.Example.BusinessCore;


    public interface IStore {

    string Name {
    get;
    set;
    }

    event System.EventHandler handler;

    string GetSomething(int a, int b, System.Random r, Store s);
    }
    }

    我的小免责声明:有很多方法可以生成和发出代码。这里展示的是一种以编程方式生成源代码的方法。有些方法有重载并采用复杂的参数——你必须在 MSDN 中查找错综复杂的内容。一些方法在 1.1、2.0 等之间发生了变化。最后,一些完成代码生成的方法已经过时,已被替代方法取代; MSDN 记录了所有这些内容。

    希望此处显示的代码可作为开始以编程方式生成接口(interface)或为此生成任何类型代码的指南。

    注意:此示例未显示如何将生成的源代码与现有代码集成,或者如何将其发送到 MSIL 或附加到现有的程序集文件中 - 我看到的其他答案显示了与这些解决方案相关的示例。

    关于.net - 有没有办法以编程方式提取接口(interface)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/484489/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com