VB.NET,但C#也可以。

我有一个MustInherit基类和基于该类的170个继承的类。为什么那么多?因为每个继承的类在Sub New()中都做不同的事情。继承的类型不添加任何新属性,但是具有不同的私有字段。他们只是简单地以不同方式处理不同组的已知变量。所以这样想:



Public MustInherit Class Base
     Public Property Width
End Class

Public Class Child1
     Inherits Base
     Private z as Integer = 7
     Public Sub New(x as integer)
           Width = 20 * x * 7
     End Sub
End Class

Public Class Child170
     Inherits Base
     Private y as Integer = 4
     Public Sub New(x as integer)
           Width = 5 * x / y
     End Sub
End Class


实际上,Sub New中包含大量基于所发送内容的处理指令(例如X as Integer)。这些处理指令将与继承类中的大量私有变量一起使用。

另外,我将知道我需要基于一个名为child1child170的相同名称的字符串变量创建哪个孩子。

因此,对于这么多继承的孩子,这里最好的方法是什么(最快,最短的编写时间,最佳性能等)。

选项:


使用Select Case调用并创建170个不同的类之一,例如:

Dim b as Base
Select Case childName
   Case "child1"
     b = New Child1(x)
   Case "child74"
     b = New Child74(x)
   Case "child103"
     b = New Child103(x)
End Select

以某种方式反映了我创建通用类的调用(伪类,因为对此我不太了解):

Dim b as Base = Activator.CreateInstance(Type.GetType("MyProjectName" & childName))


其中“ childName”是170个子级之一,然后是b.Process(x)-这是假设我使用了一个名为Process的例程,因为在CreateInstance事物中没有看到在构造函数中发送值的任何示例。
还有吗


任何帮助/建议/最佳做法都将受到欢迎(除了那些说“为什么需要170东西?不要使用170东西”的人)。

最佳答案

您可以使用反射来构建Dictionary<string/Type>实例。使用它可以根据字符串名称实例化正确的类型。您可以将字符串比较器传递给键/查找,因此它不区分大小写。在应用程序的生命周期内仅将字典构建1倍(将其保留在某些Factory类的静态字段中)。

这是用C#编写的,但是您可以将其移植到vb.net。

using System;
using System.Collections.Generic;
using System.Linq;

namespace YourNamespace
{
    public sealed class Factory
    {
        private static readonly Dictionary<string, Type> TypeLookup;

        static Factory()
        {
            // You could iterate over additional assemblies if needed
            // the key is assumed to be the name of the class (case insensitive)

            TypeLookup = typeof(Factory).Assembly.GetTypes()
                .Where(t => t.IsClass && !t.IsAbstract && typeof(SomeBase).IsAssignableFrom(t))
                .ToDictionary(t => t.Name, t => t, StringComparer.OrdinalIgnoreCase);
        }

        public SomeBase Create(string name)
        {
            Type t;
            if (TypeLookup.TryGetValue(name, out t))
            {
                return (SomeBase) Activator.CreateInstance(t);
            }
            throw new ArgumentException("Could not find type " + name);
        }
    }

    public abstract class SomeBase { }
    public class Child1 : SomeBase { }
    public class Child2 : SomeBase { }
    public class Child3 : SomeBase { }
}


呼叫码

var factory = new Factory();
var child1 = factory.Create("child1");

07-26 06:15