2

我最常用的迷你模式是:

VideoLookup = new ArrayList  { new ArrayList { buttonVideo1, "Video01.flv" },
                               new ArrayList { buttonVideo2, "Video02.flv" },
                               new ArrayList { buttonVideo3, "Video03.flv" }, 
                               new ArrayList { buttonVideo4, "Video04.flv" },
                               new ArrayList { buttonVideo4, "Video04.flv" }
                             };

这意味着,我可以将单击的按钮与 ArrayList 中的每个项目进行比较,而不是每个按钮都有一个 case 的 switch 语句。然后,当我找到匹配项时,我会启动正确的文件(尽管“查找”第二部分的操作可能是委托或其他任何内容)。

主要的好处是我没有记住为每个 switch 语句案例添加所有正确代码的问题,我只是在查找 ArrayList 中添加了一个新项目。

(是的,我知道使用 ArrayList 不是最好的方法,但它是旧代码。而且我知道每次循环遍历数组不如使用 switch 语句高效,但这段代码不在紧环)

有没有其他人有任何他们使用的迷你模式来节省时间/精力或使代码更具可读性?它们不必只是与 GUI 相关

更新:不要复制这段代码,我知道它很糟糕,但我没有意识到有多糟糕。改用这样的东西。

Hashtable PlayerLookup = new Hashtable();
PlayerLookup.Add(buttonVideo1, "Video01.flv");
PlayerLookup.Add(buttonVideo2, "Video02.flv");
PlayerLookup.Add(buttonVideo3, "Video03.flv");
PlayerLookup.Add(buttonVideo4, "Video04.flv");

string fileName = PlayerLookup[currentButton].ToString();            
4

9 回答 9

5

拜托拜托请使用这个版本。

VideoLookup = new Dictionary<Button, string> {
    { buttonVideo1, "Video01.flv" },
    { buttonVideo2, "Video02.flv" },
    { buttonVideo3, "Video03.flv" }, 
    { buttonVideo4, "Video04.flv" },
    { buttonVideo4, "Video04.flv" }
};
于 2009-06-13T01:32:00.490 回答
3

您可以创建一个结构或对象,其中包含一个按钮引用和一个表示文件名的字符串,然后是这些内容的列表。或者,您可以只使用字典,让自己更轻松。很多改进的方法。:)

于 2009-02-13T20:32:42.580 回答
3

关于开关的话题,我写了很多这样的东西:

public Object createSomething(String param)
{
    return s == null                          ? new NullObject() :
           s.equals("foo")                    ? new Foo() :
           s.equals("bar")                    ? new Bar() :
           s.equals("baz") || s.equals("car") ? new BazCar() :
                                                new Object();
}

我认为与常规 switch 语句相比,它看起来更具可读性,并且能够进行更复杂的比较。是的,它会更慢,因为你需要比较每个条件,但 99% 的时间并不重要。

于 2009-02-13T20:36:57.733 回答
3

在 Java 中,我有时会发现实现公共接口的私有内部类对于由紧密耦合元素组成的对象非常有帮助。我已经看到在使用 Allen Holub 的Visual Proxy架构创建 UI 的上下文中讨论过这个迷你模式(习语),但除此之外没有太多。据我所知,它没有名字。

例如,假设您有一个可以提供迭代器的 Collection 接口:

public interface Collection
{
  ...

  public Iterator iterate();
}

public interface Iterator
{
  public boolean hasNext();
  public Object next();
}

如果您有一个实现 Collection 的 Stack,那么您可以将其 Iterator 实现为私有内部类:

public class Stack implements Collection
{
  ...

  public Iterator iterate()
  {
    return new IteratorImpl();
  }

  private class IteratorImpl implements Iterator
  {
    public boolean hasNext() { ... }
    public Object next() { ... }
  }
}

Stack.IteratorImpl 可以完全访问 Stack 的所有私有方法和字段。同时,Stack.IteratorImpl 对除 Stack 之外的所有人都是不可见的。

Stack 和它的 Iterator 往往是紧密耦合的。最坏的情况是,将 Stack 的 Iterator 实现为公共类可能会迫使您破坏 Stack 的封装。私有内部类可让您避免这种情况。无论哪种方式,您都可以避免使用真正的实现细节来污染类层次结构。

于 2009-04-17T23:20:18.380 回答
2

在我的上一份工作中,我编写了 Andrei Alexandrescu 和 Petru Marginean 在 C++ 中引入的强制概念的 C# 版本(原始文章在这里)。

这真的很酷,因为它可以让您在不中断流程的情况下将错误处理或条件检查与正常代码交织在一起 - 例如:


string text = Enforce.NotNull( myObj.SomeMethodThatGetsAString(), "method returned NULL" );

这将检查第一个参数是否为空,如果是则抛出带有第二个参数作为消息的 EnforcementException,否则返回第一个参数。也有采用字符串格式参数的重载,以及允许您指定不同异常类型的重载。

您可能会争辩说,这种事情在 C# 中的相关性较低,因为运行时检查更好并且已经提供了相当丰富的信息 - 但是这个习惯用法让您可以更接近源代码并提供更多信息,同时保持表达性。

我使用相同的系统进行前后条件检查。

我可能会写一个开源版本并从这里链接它。

于 2009-02-13T23:59:42.643 回答
1

因为当我快速编写代码时(截止日期!截止日期!为什么我在 stackoverflow.com 上?截止日期!),我会得到这样的代码:

Button1.Click += (o,e) => { DoSomething(foo); };

这会在某些时候导致我的内存泄漏吗?我不知道!这可能值得一个问题。确认!截止日期!

于 2009-06-13T01:43:05.737 回答
0

对于 Windows 窗体,我经常使用 Tag 字段来放置一个伪命令字符串,这样我就可以为一组共享的按钮提供一个事件处理程序。这对于做几乎相同的事情但参数化的按钮特别有效。

在您的第一个示例中,我会将按钮的标记设置为等于视频文件的名称——无需查找。

对于具有某种形式的基于文本的命令处理器来调度操作的应用程序,标签是一个刚刚输入命令处理器的字符串。效果很好。

(顺便说一句:我已经看到用于迷你模式的术语“成语”......)

于 2009-02-13T21:01:20.670 回答
0

我开始在 C# 中看到的一个新习惯用法是使用闭包参数来封装该方法需要运行的一些配置或设置。这样,您可以控制代码必须从您的方法中运行的相对顺序。

这被 Martin Fowler 称为嵌套闭包:http: //www.martinfowler.com/dslwip/NestedClosure.html

于 2009-06-13T01:18:36.277 回答
0

也许已经有更好的方法来做到这一点(vbEx2005/.Net2.0),但我发现有一个通用的委托创建者类是有用的,它接受一个接受一些参数的方法,以及任何一个的值, 或除一个之外的所有参数,并产生一个委托,该委托在调用时将使用指定的参数调用指定的函数。与 ParameterizedThreadStart 等基于 ParamArray 的事物不同,一切都是类型安全的。

例如,如果我说:

Sub Foo(param1 作为整数,param2 作为字符串)
    ...
结束子

...
  Dim theAct as Action(of Integer) = _
      ActionOf(of Integer).NewInv(AddressOf Foo,"Hello there")

  法案(5)
...

结果将是在声明 Foo 的对象上调用 Foo(5, "Hello there")。不幸的是,我最终不得不为我想要支持的每个不同数量的参数拥有单独的泛型类和方法,但是将所有的剪切和粘贴都放在一个文件中,而不是让额外的代码分散在各处来创建适当的代表。

于 2010-09-27T19:10:47.153 回答