c# - 我怎样才能实现我自己的外部类型?

标签 c# .net-3.5 refactoring extern automated-refactoring

在我们的产品中,我们有称为“服务”的东西,它们是产品不同部分之间(尤其是语言之间——内部语言、C、Python 和 .NET)之间的基本通信方式。

目前代码是这样的(Services.Execute utilizing params object[] args):

myString = (string)Services.Execute("service_name", arg1, arg2, ...);

我宁愿能够编写这样的代码并获得类型检查和更简洁代码的好处:

myString = ServiceName(arg1, arg2, ...);

这可以通过一个简单的函数来实现,

public static string ServiceName(int arg1, Entity arg2, ...)
{
    return (string)Services.Execute("service_name", arg1, arg2, ...);
}

但这相当冗长,并且在为大量服务执行此操作时并不像我打算做的那样容易管理。

看到 externDllImportAttribute 是如何工作的,我希望可以通过这样的方式将其连接起来:

[ServiceImport("service_name")]
public static extern string ServiceName(int arg1, Entity arg2, ...);

但我根本不知道如何实现这一点,而且似乎找不到任何相关文档(extern 似乎是一个定义相当模糊的问题)。我发现的最接近的是一个有点相关的问题,How to provide custom implementation for extern methods in .NET?无论如何,这并没有真正回答我的问题,而且有些不同。 C# 语言规范(尤其是在版本 4.0 中,第 10.6.7 节,外部方法)没有帮助。

因此,我想提供外部方法的自定义实现;这可以实现吗?如果是这样,怎么做到的?

最佳答案

C# extern 关键字做的很少,它只是告诉编译器方法声明不会有主体。编译器会进行最低限度的检查,它坚持要求您也提供一个属性,任何事情都会发生。所以这个示例代码将编译得很好:

   class Program {
        static void Main(string[] args) {
            foo();
        }

        class FooBar : Attribute { }

        [FooBar]
        static extern void foo();
    }

但它当然不会运行,抖动在声明中举起手来。这是实际运行这段代码所需要的,抖动的工作就是为此生成适当的可执行代码。所需要的是抖动识别该属性。

您可以在 SSCLI20 distribution 中抖动的源代码中看到这一点。 , clr/src/md/compiler/custattr.cpp源码文件,RegMeta::_HandleKnownCustomAttribute()函数。这是适用于 .NET 2.0 的代码,我不知道它的添加会影响方法调用。您将看到它处理以下与方法调用的代码生成相关的属性,这些属性将使用 extern 关键字:

  • [DllImport],你肯定知道

  • [MethodImpl(MethodImplOptions.InternalCall)],一种在 CLR 而不是框架中实现的方法上使用的属性。它们是用 C++ 编写的,CLR 有一个链接到 C++ 函数的内部表。一个典型的例子是 Math.Pow() 方法,我在 this answer 中描述了实现细节。 .该表不能以其他方式扩展,它在 CLR 源代码中是硬烘焙的

  • [ComImport],一种将接口(interface)标记为在别处实现的属性,总是在 COM 服务器中实现。您很少直接对该属性进行编程,而是使用由 Tlbimp.exe 生成的互操作库。此属性还需要 [Guid] 属性来提供接口(interface)所需的 guid。这在其他方面类似于 [DllImport] 属性,它生成对非托管代码的 pinvoke 类调用,但使用 COM 调用约定。这当然只有在您的机器上确实有所需的 COM 服务器时才能正常工作,否则它可以无限扩展。

在此函数中可以识别更多属性,但它们与调用别处定义的代码无关。

因此,除非您编写自己的抖动,否则使用 extern 并不是获得所需内容的可行方法。如果您无论如何都想追求这个,您可以考虑 Mono 项目。

纯托管的常见可扩展性解决方案是基本上被遗忘的 System.AddIn 命名空间、非常流行的 MEF 框架和 AOP 解决方案(如 Postsharp)。

关于c# - 我怎样才能实现我自己的外部类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13736156/

相关文章:

c# - 使用计时器和游戏循环

c# - 在网站的 bin 文件夹中包含 csc.exe 的安全问题

c# - Linq Sql 数据库上下文缺失方法

c# - 从磁盘解析大数据文件比在内存中解析慢得多?

c# - 确定有多少用户查看了页面

c# - 在保存和从上下文中删除之前验证实体

.net - CallContext.SetData() - 当线程变为事件-非事件-事件 (TPL) 时对象是否可用?

python - pyCharm:依赖代码的应用程序的安全重构信息

objective-c - 如何重构此 Objective-C 代码

java - 具有不同返回值的一种方法的重构模式