【问题标题】:Deferred initialization "proxy" in C#C# 中的延迟初始化“代理”
【发布时间】:2022-03-31 03:24:46
【问题描述】:

假设我有一个对象树,其中包含来自(相当大的)一组类的对象;类或多或少在我的控制之下(比如说,每个都实现IBaseInterface,用于语义类型)。 树通常以深度优先的方式填充。但是,有时必须在执行流程中的不同位置创建节点;因此我需要一些可以充当对象的占位符(类似代理)的东西。占位符应包含对其创建位置的引用,而不会对基础类型/对象(装饰器样式)产生任何其他干扰。

我在想类似的东西

interface IPlaceholder
{
    PositionReference RealLocation { get; }
}

class Placeholder<T> : T, IPlaceholder
{
    PositionReference RealLocation { get; private set; }
}

但是,这不起作用,因为 C# 不能让泛型类​​从其类型参数继承。

当然,一种蛮力方法是在运行时动态生成符合规范的类;但这似乎有点太极端了(如果我必须手动摆弄 Reflection.Emit 会很麻烦)。

创建此类占位符对象的最佳方法是什么?

(额外说明:这很像Lazy&lt;T&gt;,只是对象通常应为原始类型;否则,在处理父节点之前无法构造代理对象。)

【问题讨论】:

  • 不同的位置是什么意思?是树中的深度(级别)吗?它有哪个父母?你能解释一下吗?
  • 不同位置的具体示例:树是从流中生成的,LL-parser 样式。流(有时)具有数据在流中不同位置的节点的令牌。令牌中没有搜索信息,并且如果不解析令牌,树的生成就无法继续。因此,代理节点数据在构建树后匹配。

标签: c# design-patterns generic-programming


【解决方案1】:

您所追求的是一个虚拟代理。这是一个简单的例子。假设您有一个急切加载的 Bitmap 类:

interface IBitmap { void Draw(); }
class Bitmap : IBitmap
{
  Bitmap(string filename)
  {
    WriteLine($"Loading bitmap from {filename}");
  }
  void Draw()
  {
    WriteLine($"Drawing bitmap!");
  }
}

虚拟代理是在需要时才加载位图的包装器:

class VirtualBitmap : IBitmap
{
  private Bitmap bitmap;
  private string filename;
  public VirtualBitmap(string filename)
  {
    this.filename = filename;
  }
  void Draw()
  {
    if (bitmap == null) bitmap = new Bitmap(filename);
    bitmap.Draw();
  }
}

请随意使用Lazy&lt;T&gt;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-05-10
    • 1970-01-01
    • 2011-11-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-01
    • 1970-01-01
    相关资源
    最近更新 更多