C#设计-如何在没有空接口的情况下实质上如何将类和枚举分组到列表中?

Haighstrom

我正在设计一个文本渲染器。我正在建立如何将字符串分成几行以适合文本框的逻辑。我要这样做的方法是,首先将完整的字符串分成“单词”,“空格”和“换行符”,然后构建一种算法来测量一行中可以容纳多少行,然后再移动到下一行。

但是,“ Word”必须是一个类/结构,因为它要保留“ FontStyle”,“ Colour”等额外属性。“ Space”和“ NewLine”只是标记-它们不需要任何数据。

目前,我有以下框架:

interface ILineComponent
{
}

struct Word : ILineComponent
{
    public string Text;
    public FontStyle Style;
    public Colour Colour;

    public Word(string text, FontStyle style, Colour colour)
    {
        Text = text;
        Style = style;
        Colour = colour;
    }
}

struct Space : ILineComponent
{
}

struct NewLine : ILineComponent
{
}

struct Line
{
    public List<ILineComponent> Segments;

    public Line(List<ILineComponent> segments)
    {
        Segments = segments;
    }
}

然后,我的想法是,我将遍历这条直线,并测量将一条线(或单词,...,换行符)拆分成另一行之前要容纳多少个(单词,空格,...,单词,空格)。目前,这将利用如下逻辑:

foreach (ILineComponent component in line)
{
    if (component is Word)
    //..
    else if (component is Space)
    //...
    else if (component is NewLine)
    //...
}

但是该设计违反了CA1040

我该如何更好地设计?

托马斯·韦勒

空接口不仅违反了CA1040。它也违反了DRY的干净代码原则,因为很有可能在代码的多个位置使用这些if / else语句。如果不根据接口的存在做出一些决定,您将对空接口怎么办?

是的,让我们摆脱它。感谢您关心编译器警告并尝试编写更好的代码。

首先,我认为a的定义Space不完整。没有字体也无法确定空间的宽度。因此,我认为空间应类似于Word也许它不需要颜色,当然也不需要文本作为参数。

struct Space : ILineComponent
{
    public readonly string Text = " ";
    public FontStyle Style;

    public Word(FontStyle style)
    {
        Style = style;
    }
}

我不认为这是的特殊情况Word稍后您会看到,为什么会这样。这是因为我提出接口的方式。

我也认为此代码具有误导性

foreach (ILineComponent component in line)

由于您还不知道多少行,因此该变量line不正确。这应该是componentsOfText或类似的。在循环内部,您将在需要时开始新行。

接下来,我建议您将这三个组件需要做的所有事情都放在界面中。据我了解,这是:

interface ILineComponent
{
    int Measure();
    bool IsTrimmedAtEndOfLine;
    bool TerminatesLine;
}

对于NewLineMeasure()只需返回0。

您的代码如下所示:

//       IList<LineComponent> is a line
// IList<       -"-          > are many lines
// Maybe you want to define an alias for that, or even a class
IList<IList<ILineComponent>> lines = new ...;

int remainingSpace = 2000; // px or whatever
while (componentsOfText.Length > 0)
{
     component = componentsOfText[0];

     var space = component.Measure();
     if (space > remainingSpace)
     {
          // finish current line and start a new one, 
          // i.e. add a new List<LineComponent>,
          // reset remaining space,
          // do the line post processing (e.g. space width adjustment)

          // Do not remove component from the list
          continue;
     }

     if (component.TerminatesLine)
     {
           // Finish current line and start a new line
           // just as before
     }

     remainingSpace -= space;
     componentsOfText.Remove(component);
}

对于“完成当前行并开始新行”部分:

var lastitem = line[line.Count - 1];
if (lastitem.IsTrimmedAtEndOfLine)
{
    line.Remove(lastitem);
}

// start the second pass for calculating the width of a space etc.

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

C#中的设计类

来自分类Dev

如何将枚举绑定到C#中具有空字段的组合框

来自分类Dev

如何在C#中设计键盘?

来自分类Dev

C#中的类设计结构

来自分类Dev

如何访问设计 Windows 窗体 C#

来自分类Dev

C#树节点类设计

来自分类Dev

C#中的原型设计模式

来自分类Dev

C#中API的设计通知结构

来自分类Dev

在C#中实现ISP设计模式

来自分类Dev

C#中API的设计通知结构

来自分类Dev

C#中的原型设计模式

来自分类Dev

如何使用C#中的委托来实现使用接口和实现类的类似设计(从Java)

来自分类Dev

C#中接口和泛化设计的建议

来自分类Dev

如何在C#中实现单例设计模式?

来自分类Dev

C#中具有通用类和接口的类设计

来自分类Dev

C#中的异步套接字类的设计

来自分类Dev

C#中的异步套接字类的设计

来自分类Dev

C#类设计问题以使其可测试

来自分类Dev

C#耦合类-强类型结构设计

来自分类Dev

需要有关C#设计模式的建议

来自分类Dev

C#设计器中的Crystal Reports异常

来自分类Dev

静态构造函数-C#中的Singleton设计模式

来自分类Dev

C#中的状态设计模式的概念示例

来自分类Dev

C#设计器中的Crystal Reports异常

来自分类Dev

如何在C#中没有System.Web dll的情况下进行UrlDecode

来自分类Dev

如何在 C# 中设置 DI/IoC 和/或工厂模式设计

来自分类Dev

继承List <T>时,如何在没有构造函数的情况下将数据传递给父类?C#

来自分类Dev

Json.Net-如何在没有外部括号的情况下序列化C#列表?

来自分类Dev

Json.Net-如何在没有外部括号的情况下序列化C#列表?