C# 基于抽象类型创建类
我有基于标准抽象类的selveral类,它们将从我使用int数组的示例的datatable中加载。该类将按类型初始化,然后加载该类的特定细节。目前,我是用switch语句来实现的,但是否可以用另一种方式实现呢C# 基于抽象类型创建类,c#,oop,C#,Oop,我有基于标准抽象类的selveral类,它们将从我使用int数组的示例的datatable中加载。该类将按类型初始化,然后加载该类的特定细节。目前,我是用switch语句来实现的,但是否可以用另一种方式实现呢 class Program { static void Main(string[] args) { var list = new[] {1, 1, 3, 2, 2, 4}; TypeBase typeClass = null;
class Program
{
static void Main(string[] args)
{
var list = new[] {1, 1, 3, 2, 2, 4};
TypeBase typeClass = null;
foreach (var i in list)
{
switch (i)
{
case 1:
{
typeClass = new Type1();
break;
}
case 2:
{
typeClass = new Type2();
break;
}
case 3:
{
typeClass = new Type3();
break;
}
}
}
if (typeClass != null)
{
typeClass.LoadDetails();
}
}
}
public class TypeBase
{
public int Type { get; set; }
public virtual void LoadDetails()
{
throw new NotImplementedException();
}
}
public class Type1 : TypeBase
{
public override void LoadDetails()
{
// Load type Specific details
}
}
public class Type2 : TypeBase
{
public override void LoadDetails()
{
// Load type Specific details
}
}
public class Type3 : TypeBase
{
public override void LoadDetails()
{
// Load type Specific details
}
}
理想情况下,您应该遵循工厂方法来满足此类要求。否则,如果您乐意为您的子类遵循约定,那么下面是一个便宜的技巧
using System;
using System.Runtime.Remoting;
namespace ConsoleApplication1
{
internal class Program
{
private static void Main(string[] args)
{
var list = new[] {1, 1, 3, 2, 2, 4};
TypeBase typeClass = null;
foreach (var i in list)
{
ObjectHandle handle = Activator.CreateInstanceFrom("ConsoleApplication1", string.Format("{0}{1}", "Type", i));//Program- Name of the assembl
var typeBase = (TypeBase) handle.Unwrap();
typeBase.Type = i;
typeClass.LoadDetails();
}
}
}
public class TypeBase
{
public int Type { get; set; }
public virtual void LoadDetails()
{
throw new NotImplementedException();
}
}
public class Type1 : TypeBase
{
public override void LoadDetails()
{
// Load type Specific details
}
}
}
注意:我个人不会遵循这种方法,我更喜欢工厂方法或相当数量的开关。这只是闪现一种可能性而已。如果您决定遵循的要求,请进行相应的测试和修改。理想情况下,您应该遵循工厂方法来满足此类要求。否则,如果您乐意为您的子类遵循约定,那么下面是一个便宜的技巧
using System;
using System.Runtime.Remoting;
namespace ConsoleApplication1
{
internal class Program
{
private static void Main(string[] args)
{
var list = new[] {1, 1, 3, 2, 2, 4};
TypeBase typeClass = null;
foreach (var i in list)
{
ObjectHandle handle = Activator.CreateInstanceFrom("ConsoleApplication1", string.Format("{0}{1}", "Type", i));//Program- Name of the assembl
var typeBase = (TypeBase) handle.Unwrap();
typeBase.Type = i;
typeClass.LoadDetails();
}
}
}
public class TypeBase
{
public int Type { get; set; }
public virtual void LoadDetails()
{
throw new NotImplementedException();
}
}
public class Type1 : TypeBase
{
public override void LoadDetails()
{
// Load type Specific details
}
}
}
注意:我个人不会遵循这种方法,我更喜欢工厂方法或相当数量的开关。这只是闪现一种可能性而已。如果决定遵循有几种解决方案,请进行相应的测试和修改 一,。使用反射创建类型 Nair已经给出了这个解决方案。因为我希望您的类型不会被称为Type1、Type2等。我假设这对您不起作用 二,。将类型存储在具有类型的词典中 创建一个将替换开关/机箱的字典。它包含您需要创建的类型:
Dictionary<int, Type> types = new Dictionary<int, Type>
{
{1, typeof(Type1)},
{2, typeof(Type2)},
{3, typeof(Type3)}
};
此解决方案比解决方案1快,因为只使用了一个反射操作
三,。使用工厂方法将类型存储在字典中
创建一个将替换开关/机箱的字典。它将包含工厂方法:
Dictionary<int, Func<TypeBase>> factories = new Dictionary<int, Func<TypeBase>>
{
{1, () => new Type1()},
{2, () => new Type2()},
{3, () => new Type3()}
};
此解决方案比解决方案3快,因为每次调用都不会创建实例
一些旁注
为什么不使用带有一个成员LoadDetails的接口?在您的示例中,从未使用成员类型。
为什么不将TypeBase.LoadDetails作为抽象方法?
如果您的键值总是键入It32,并且处于连续的范围内,则可以考虑使用列表或甚至是数组,这将比字典更快。
有几种解决方案 一,。使用反射创建类型 Nair已经给出了这个解决方案。因为我希望您的类型不会被称为Type1、Type2等。我假设这对您不起作用 二,。将类型存储在具有类型的词典中 创建一个将替换开关/机箱的字典。它包含您需要创建的类型:
Dictionary<int, Type> types = new Dictionary<int, Type>
{
{1, typeof(Type1)},
{2, typeof(Type2)},
{3, typeof(Type3)}
};
此解决方案比解决方案1快,因为只使用了一个反射操作
三,。使用工厂方法将类型存储在字典中
创建一个将替换开关/机箱的字典。它将包含工厂方法:
Dictionary<int, Func<TypeBase>> factories = new Dictionary<int, Func<TypeBase>>
{
{1, () => new Type1()},
{2, () => new Type2()},
{3, () => new Type3()}
};
此解决方案比解决方案3快,因为每次调用都不会创建实例
一些旁注
为什么不使用带有一个成员LoadDetails的接口?在您的示例中,从未使用成员类型。
为什么不将TypeBase.LoadDetails作为抽象方法?
如果您的键值总是键入It32,并且处于连续的范围内,则可以考虑使用列表或甚至是数组,这将比字典更快。
您可以使用反射来尝试解析类型名称:var type=type.GetTypetypename并使用Activator.CreateInstancetype来创建实例您可以使用反射来尝试解析类型名称:var type=type.GetTypetypename并使用Activator.CreateInstancetype来创建实例您可以详细解释一下声明:理想情况下,您应该按照工厂方法来满足这种要求。工厂方法是一种设计模式,在这种情况下非常理想。你可以阅读更多关于它的内容。不要限制自己尝试搜索更多工厂方法实现。它的好处是,它为您提供了更多的静态类型语言特性,没有运行时异常的空间。这就是为什么我更喜欢工厂而不是我上面的草稿。你能解释一下你的陈述吗:理想情况下,你应该遵循工厂方法来满足这样的要求。工厂方法是一种设计模式,在这种情况下是理想的。你可以阅读更多关于它的内容。不要限制自己尝试搜索更多工厂方法实现。它的好处是,它为您提供了更多的静态类型语言特性,没有运行时异常的空间。这就是为什么我更喜欢工厂而不是我上面的草稿。我将看一看,并使用您的建议创建一个实现,看起来非常有趣-将使用您的sugestion查看并创建一个实现,看起来非常有趣-
TypeBase typeClass;
if (baseClasses.TryGetValue(i, out baseClass))
{
typeClass.LoadDetails();
}