BlackWhiteYoshi/InlineComposition
GitHub: BlackWhiteYoshi/InlineComposition
一个基于Roslyn的C#源代码生成器,通过在编译期将其他类或结构体的成员合并到目标类型中,实现结构体继承和多重继承的变通方案。
Stars: 15 | Forks: 0
# InlineComposition
一个源代码生成器,用于将其他类的内容合并到一个类中。
一种用于结构体继承或多重继承的简单变通方案。

- 内联获取类型的字段、属性、事件和方法(包括构造函数和终结器)成员。
- 内联成员的特性和摘要也会被内联。
- 继承和接口实现声明也会被内联。
- 混合使用类和结构体能正常工作(在类中内联结构体,反之亦然)。
## 类型层次结构 / 多态 继承不仅提供了基类的所有内容,还提供了类型层次结构和多态。 如果需要类型层次结构或多态,可以使用接口来获得相同的功能。 ``` 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。
在这种情况下,您的引用项目中会定义两次特性,并且您会收到相关警告。
通过在引用项目中定义此常量,您可以阻止一次生成,从而使特性仅在引用的项目中定义一次。
## 类型层次结构 / 多态 继承不仅提供了基类的所有内容,还提供了类型层次结构和多态。 如果需要类型层次结构或多态,可以使用接口来获得相同的功能。 ``` using InlineCompositionAttributes; public interface IBaseA { ... } public interface IBaseB { ... } public class BaseA : IBaseA { ... } public class BaseB : IBaseB { ... } [Inline
## 冲突 具有相同标识符的成员将被合并为单个成员。 请确保合并后的成员具有相同的签名。 方法体会被合并在一起,每个方法会依次执行。 不支持嵌套类型的合并。 如果发生嵌套类型冲突,将采用第一个而忽略其余的。 ``` 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
## 泛型类 支持内联泛型类。 但是,将具体类型插入到类型参数的位置是通过简单的文本替换完成的。 在某些情况下,可能会出现应该替换/不该替换的地方被错误处理的情况。 因此,在内联泛型类时,最好仔细检查结果。 ``` using InlineCompositionAttributes; public class Base
## 特性 - InlineAttribute 生成一个同名的类,并用类型参数中的类/结构体的内容填充它。 ``` using InlineCompositionAttributes; [Inline
- 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
- InlineMethodAttribute 重写普通方法并添加您自己的代码在原生情况下是不可能的。 *InlineMethodAttribute* 为向内联方法添加代码提供了支持。 被修饰的方法的内容将被添加到 *MethodName* 参数中指定的内联方法中,并接受相同的参数。 ``` using InlineCompositionAttributes; public class Base : IDisposable { public void Dispose() { Console.WriteLine("base"); } } [Inline
- InlineConstructorAttribute *InlineConstructorAttribute* 允许您向内联的构造函数添加代码。 被装饰的方法的内容将被添加到内联的构造函数中。 ``` using InlineCompositionAttributes; public class Base { public Base() { Console.WriteLine("base"); } } [Inline
- InlineFinalizerAttribute *InlineFinalizerAttribute* 允许您向内联的终结器添加代码。 被装饰的方法的内容将被添加到内联的终结器中。 ``` using InlineCompositionAttributes; public class Base { ~Base() { Console.WriteLine("base"); } } [Inline
- NoInlineAttribute 用此特性装饰的成员将被忽略。 ``` using InlineCompositionAttributes; public class MyBase { [NoInline] private int myField; public int MyProperty { get; set; } } [Inline
## 禁用特性生成 您可以通过为编译定义常量来禁用特性的生成: ```
标签:Roslyn, SOC Prime, Waymore结果处理, 代码合并, 代码复用, 代码生成, 元编程, 反向工程, 多人体追踪, 多态, 多重继承, 工作流自动化, 开发工具, 接口继承, 数据管道, 渗透测试工具, 源代码生成器, 源码分析, 类型层次, 结构体继承, 编程语法糖, 编译器特性, 软件工程