免责声明
这只是一个演示。不要在生产中使用它。
你对 c# 提出了一些不自然的要求。我喜欢它。准备观看一些魔术。
但让我们从修补初始代码开始。首先,让我们将 Main 类名称更改为 Derived。
众所周知,字段内联初始化是一种语法糖。编译器对所有构造函数进行初始化。我们也会。让我们添加空合并。起初它不会影响结果,但接下来将是一个很好的帮助。
我们还应该将我们的类放入一个单独的类库(例如 ClassLibrary)中。
所以我们有:
namespace ClassLibrary
{
public class Base
{
public string myString;
public Base(string str)
{
myString = myString ?? "Hi";
myString += str;
}
}
public class Derived : Base
{
public Derived() : base(" world")
{
base.myString = "Hello";
}
}
}
然后编译库,创建控制台应用程序并通过添加引用添加对已编译 dll 的引用... -> 浏览 -> 浏览...
添加类似你的代码:
using System;
using ClassLibrary;
namespace ConsoleApp
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine(new Derived().myString);
}
}
}
输出只是
Hello
和你一样。
现在用 ildasm 打开 dll 并将其转储(文件 -> 转储,检查转储 IL 代码)到 ClassLibrary.il 并退出 ildasm。使用任何文本编辑器打开 ClassLibrary.il 并找到 Derived 类构造函数。它以.class public auto ansi beforefieldinit ClassLibrary.Derived 开头并包含:
IL_0000: ldarg.0
IL_0001: ldstr " world"
IL_0006: call instance void ClassLibrary.Base::.ctor(string)
IL_000b: nop
IL_000c: nop
IL_000d: ldarg.0
IL_000e: ldstr "Hello"
IL_0013: stfld string ClassLibrary.Base::myString
IL_0018: ret
将其更改为(在 IL 中手动在任何地方调用基类构造函数):
IL_0000: ldarg.0
IL_0001: ldstr "Hello"
IL_0006: stfld string ClassLibrary.Base::myString
IL_000b: nop
IL_000c: nop
IL_000d: ldarg.0
IL_000e: ldstr " world"
IL_0013: call instance void ClassLibrary.Base::.ctor(string)
IL_0018: ret
然后保存 ClassLibrary.il 并从命令提示符运行:
"%ILASM_LOCATION%\ilasm.exe" "%ClassLibrary.il_LOCATION%\ClassLibrary.il" /dll /output:"%ClassLibrary.dll_LOCATION%\ClassLibrary.dll"
再次运行控制台应用程序并查看:
Hello world
使用 ILSpy 派生类外观打开:
public class Derived : Base
{
public Derived()
{
myString = "Hello";
base..ctor(" world");
}
}
但放到 ClassLibrary 项目中:
错误 CS1001 标识符应为...
错误 CS7036 没有给出与 'Base.Base(string)' 的所需形参 'str' 相对应的参数...
错误 CS0117 'Base' 不包含 '' 的定义...