c# - 使用 Is/As 运算符的工厂方法

标签 c# factory

我有一个类似于以下代码片段的工厂。 Foo 是 Bar 的包装类,在大多数情况下(但不是全部),存在 1:1 映射。通常,Bar 不知道关于 Foo 的任何信息,但 Foo 获取了 Bar 的一个实例。是否有更好/更清洁的方法来执行此操作?

public Foo Make( Bar obj )
{
    if( obj is Bar1 )
        return new Foo1( obj as Bar1 );
    if( obj is Bar2 )
        return new Foo2( obj as Bar2 );
    if( obj is Bar3 )
        return new Foo3( obj as Bar3 );
    if( obj is Bar4 )
        return new Foo3( obj as Bar4 ); // same wrapper as Bar3
    throw new ArgumentException();
}

乍一看,这个问题可能看起来像是重复的(也许是),但我还没有看到完全相同的问题。这是一个接近但不完全是的:

Factory based on Typeof or is a

最佳答案

如果这些是引用类型,那么在 is 之后调用 as 是不必要的开销。通常的习惯用法是使用 as 进行转换并检查是否为 null。

从微优化退后一步,看起来您可以使用您链接到的文章中的一些技术。具体来说,您可以创建一个以类型为键的字典,其值是构造实例的委托(delegate)。代表将接受 Bar 的(子)并返回 Foo 的(子)。理想情况下,Foo 的每个 child 都会将自己注册到字典中,字典在 Foo 本身中可以是静态的。

下面是一些示例代码:

// Foo creator delegate.
public delegate Foo CreateFoo(Bar bar);

// Lookup of creators, for each type of Bar.
public static Dictionary<Type, CreateFoo> Factory = new Dictionary<Type, CreateFoo>();

// Registration.
Factory.Add(typeof(Bar1), (b => new Foo1(b)));

// Factory method.
static Foo Create(Bar bar)
{
    CreateFoo cf;
    if (!Factory.TryGetValue(bar.GetType(), out cf))
        return null;

    return cf(bar);
}

关于c# - 使用 Is/As 运算符的工厂方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2959303/

相关文章:

c# - EPPlus 显示系统参数异常

angularjs - 不使用全局变量的 angular.factory 中 $resource 的动态 URL

带有 boost::noncopyable 的 C++ 工厂函数

c# - 如何防止类从外部实例化但保持可用?

c# - 是否可以从 IntPtr + 大小创建托管字节数组?

c# - 构建名称字段为 A 或 B 的 QueryExpression

c# - 如何使用 PdfSharp 创建注释以突出显示现有 PDF 的文本

c# - 如何通过不带资源文件的 cmake 为 C# Windows 窗体应用程序设置图标?

http - AngularJS 工厂 http 返回空

java - java中的自然返回类型是什么?