BlackWhiteYoshi/InlineComposition

GitHub: BlackWhiteYoshi/InlineComposition

一个基于Roslyn的C#源代码生成器,通过在编译期将其他类或结构体的成员合并到目标类型中,实现结构体继承和多重继承的变通方案。

Stars: 15 | Forks: 0

# InlineComposition 一个源代码生成器,用于将其他类的内容合并到一个类中。 一种用于结构体继承或多重继承的简单变通方案。 ![InlineComposition 示例](https://static.pigsec.cn/wp-content/uploads/repos/2026/04/c64b751e6f215640.png) - 内联获取类型的字段、属性、事件和方法(包括构造函数和终结器)成员。 - 内联成员的特性和摘要也会被内联。 - 继承和接口实现声明也会被内联。 - 混合使用类和结构体能正常工作(在类中内联结构体,反之亦然)。

## 类型层次结构 / 多态 继承不仅提供了基类的所有内容,还提供了类型层次结构和多态。 如果需要类型层次结构或多态,可以使用接口来获得相同的功能。 ``` using InlineCompositionAttributes; public interface IBaseA { ... } public interface IBaseB { ... } public class BaseA : IBaseA { ... } public class BaseB : IBaseB { ... } [Inline] public partial class Derived { ... } [...] Derived derived = new(); Console.WriteLine(derived is BaseA); // False Console.WriteLine(derived is BaseB); // False Console.WriteLine(derived is IBaseA); // True Console.WriteLine(derived is IBaseB); // True // polymorphism IBaseA ExampleA(derived); // polymorphism IBaseB ExampleB(derived); static void ExampleA(IBaseA baseA) { ... } static void ExampleB(IBaseB baseB) { ... } [...] // public partial class Derived : IBaseA, IBaseB { ... } ```

## 冲突 具有相同标识符的成员将被合并为单个成员。 请确保合并后的成员具有相同的签名。 方法体会被合并在一起,每个方法会依次执行。 不支持嵌套类型的合并。 如果发生嵌套类型冲突,将采用第一个而忽略其余的。 ``` using InlineCompositionAttributes; public class BaseA { public int MyProperty { get; set; } public void MyMethod() { int a = 5; Console.WriteLine(a); } } public class BaseB { public int MyProperty { get; set; } public void MyMethod() { int a = 5; Console.WriteLine(a + a); } } [Inline] public partial class Derived { ... } [...] // public partial class Derived { public int MyProperty { get; set; } public void MyMethod() { { int a = 5; Console.WriteLine(a); } { int a = 5; Console.WriteLine(a + a); } } } ```

## 泛型类 支持内联泛型类。 但是,将具体类型插入到类型参数的位置是通过简单的文本替换完成的。 在某些情况下,可能会出现应该替换/不该替换的地方被错误处理的情况。 因此,在内联泛型类时,最好仔细检查结果。 ``` using InlineCompositionAttributes; public class Base { public T MyProperty { get; set; } } [Inline>] public partial class Derived { ... } [...] // public partial class Derived { public Int32 MyProperty { get; set; } } ```

## 特性 - InlineAttribute 生成一个同名的类,并用类型参数中的类/结构体的内容填充它。 ``` using InlineCompositionAttributes; [Inline] public partial class MyClass { ... } [...] // public partial class MyClass { ... } ``` 此类最多带有 12 个类型参数。 如果需要更多,您可以轻松创建适合自己的特性。 ``` namespace InlineCompositionAttributes; [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct)] internal sealed class InlineAttribute : Attribute { } ```

- InlineBaseAttribute 被内联的类/结构体可以装饰额外的修饰符。 它本身没有任何作用,但您也可以使用它来明确您的基类/结构体的用法。 ``` using InlineCompositionAttributes; [InlineBase] // itself it does nothing public class MyClass { ... } ``` #### MapBaseType 如果此标志设置为 true,内联基类/结构体的类型所有出现的地方都将被替换为内联类/结构体的类型。 ``` using InlineCompositionAttributes; [InlineBase(MapBaseType = true)] public class Example { public Example Self => this; } [Inline] public partial class Derived { ... } [...] // public partial class Derived { public Derived Self => this; } ``` #### IgnoreInheritenceAndImplements 如果此标志设置为 true,内联类的基类和接口将被忽略。 如果您想内联继承自不同基类的类,可以使用此选项来避免继承多个类。 ``` using InlineCompositionAttributes; public abstract class BaseA { ... } public abstract class BaseB { ... } [InlineBase(IgnoreInheritenceAndImplements = true)] public class InlineA : BaseA { ... } public class InlineB : BaseB { ... } [Inline] public partial class Derived { ... } [...] // public partial class Derived : BaseB { ... } ``` #### InlineAttributes 如果此标志设置为 true,应用于此类/结构体的特性也会被内联。 [InlineBase] 特性本身将被忽略。 ``` using InlineCompositionAttributes; [SomeAttribute] [InlineBase(InlineAttributes = true)] public class Example { ... } [Inline] public partial class Derived { ... } [...] // [SomeAttribute] public partial class Derived { ... } ```

- InlineMethodAttribute 重写普通方法并添加您自己的代码在原生情况下是不可能的。 *InlineMethodAttribute* 为向内联方法添加代码提供了支持。 被修饰的方法的内容将被添加到 *MethodName* 参数中指定的内联方法中,并接受相同的参数。 ``` using InlineCompositionAttributes; public class Base : IDisposable { public void Dispose() { Console.WriteLine("base"); } } [Inline] public partial class Derived { [InlineMethod(MethodName = "Dispose")] public void DisposePartial() { Console.WriteLine("derived"); } } [...] // public partial class Derived : IDisposable { [InlineMethod(MethodName = "Dispose")] public void Dispose() { { Console.WriteLine("base"); } { Console.WriteLine("derived"); } } } ``` #### MethodName *MethodName* 是一个必需参数,用于指定要添加内容的方法的名称。 请确保参数相同,以定位到正确(重载)的方法。 ``` using InlineCompositionAttributes; public class Base { public void PrintSum(int a, int b) { Console.WriteLine(a + b); } } [Inline] public partial class Derived { [InlineMethod(MethodName = "PrintSum(int, int)")] public void PrintSumPartial(int a, int b) { Console.WriteLine(b + a); } } [...] // public partial class Derived { [InlineMethod(MethodName = "PrintSum(int, int)")] public void PrintSum() { { Console.WriteLine(a + b); } { Console.WriteLine(b + a); } } } ``` #### Modifiers 在将方法体内联到方法中时,摘要、特性和修饰符将被您的方法覆盖。 如果您希望内联的修饰符与您的方法不同,可以使用 *Modifiers* 参数。 一个常见的场景是您的方法不应可用(private),但内联的方法仍应是 public。 ``` using InlineCompositionAttributes; public class Base : IDisposable { public void Dispose() { Console.WriteLine("base"); } } [Inline] public partial class Derived { [InlineMethod(MethodName = "Dispose", Modifiers = "public")] private void DisposePartial() { Console.WriteLine("derived"); } } [...] // public partial class Derived : IDisposable { [InlineMethod(MethodName = "Dispose", Modifiers = "public")] public void Dispose() { { Console.WriteLine("base"); } { Console.WriteLine("derived"); } } } ``` #### First 当添加的代码必须在内联代码之前运行时,您可以将 *First* 参数设置为 true。 ``` using InlineCompositionAttributes; public class Base : IDisposable { public void Dispose() { Console.WriteLine("base"); } } [Inline] public partial class Derived { [InlineMethod(MethodName = "Dispose", First = true)] public void DisposePartial() { Console.WriteLine("derived"); } } [...] // public partial class Derived : IDisposable { [InlineMethod(MethodName = "Dispose")] public void Dispose() { { Console.WriteLine("derived"); } { Console.WriteLine("base"); } } } ```

- InlineConstructorAttribute *InlineConstructorAttribute* 允许您向内联的构造函数添加代码。 被装饰的方法的内容将被添加到内联的构造函数中。 ``` using InlineCompositionAttributes; public class Base { public Base() { Console.WriteLine("base"); } } [Inline] public partial class Derived { [InlineConstructor] public void ConstructorPartial() { Console.WriteLine("derived"); } } [...] // public partial class Derived { [InlineConstructor] public Derived() { { Console.WriteLine("base"); } { Console.WriteLine("derived"); } } } ``` #### Modifiers 与 *InlineMethodAttribute.Modifiers* 功能相同 #### First 与 *InlineMethodAttribute.First* 功能相同

- InlineFinalizerAttribute *InlineFinalizerAttribute* 允许您向内联的终结器添加代码。 被装饰的方法的内容将被添加到内联的终结器中。 ``` using InlineCompositionAttributes; public class Base { ~Base() { Console.WriteLine("base"); } } [Inline] public partial class Derived { [InlineFinalizer] public void FinalizerPartial() { Console.WriteLine("derived"); } } [...] // public partial class Derived { [InlineFinalizer] ~Derived() { { Console.WriteLine("base"); } { Console.WriteLine("derived"); } } } ``` #### First 与 *InlineMethodAttribute.First* 功能相同

- NoInlineAttribute 用此特性装饰的成员将被忽略。 ``` using InlineCompositionAttributes; public class MyBase { [NoInline] private int myField; public int MyProperty { get; set; } } [Inline] public partial class Derived { ... } [...] // public partial class Derived { public int MyProperty { get; set; } } ```

## 禁用特性生成 您可以通过为编译定义常量来禁用特性的生成: ``` INLINECOMPOSITION_EXCLUDE_ATTRIBUTES ``` 此功能专门针对以下用例:当您有一个项目引用另一个项目,两个项目都使用此生成器,并且您启用了 InternalsVisibleTo。 在这种情况下,您的引用项目中会定义两次特性,并且您会收到相关警告。 通过在引用项目中定义此常量,您可以阻止一次生成,从而使特性仅在引用的项目中定义一次。
标签:Roslyn, SOC Prime, Waymore结果处理, 代码合并, 代码复用, 代码生成, 元编程, 反向工程, 多人体追踪, 多态, 多重继承, 工作流自动化, 开发工具, 接口继承, 数据管道, 渗透测试工具, 源代码生成器, 源码分析, 类型层次, 结构体继承, 编程语法糖, 编译器特性, 软件工程