我很确定有几种不同的方法可以做到这一点,因为我非常接近它而没有成功使用像 Activator.CreateInstance 这样的东西,但我希望看到你对我的具体案例的意见
有没有办法避免这种开关?
b = [[-1, 2], [-2, 1], [0, 4], [3, 5], [-3, 1], [-10, -7], [6, 8]]
b.sort()
result = []
current = b[0]
for interval in b[1:]:
if current[1] >= interval[0]:
current[1] = interval[1]
else:
result.append(current)
current = interval
result.append(current)
print(result) # [[-10, -7], [-3, 5], [6, 8]]
答案 0 :(得分:5)
我的方法是使用字典来构建映射。字典可以在运行时修改,如果需要可以使用反射动态填充。
var factory = new Dictionary<ResourceType, Func<Resource>>()
{
{ ResourceType.Block, () => new Block() },
{ ResourceType.Rock, () => new Rock() },
{ ResourceType.Plant, () => new Plant() },
};
Resource r = factory[type].Invoke();
答案 1 :(得分:2)
如果类型名称相同,则不必从枚举中保存映射,否则可以使用Dictionary来保存映射。
这是另一个使用Activator.CreateInstance
仅使用对象类型的确切名称的示例。
using System;
public class Program
{
public static void Main()
{
string dog = "Dog";
var dogObj = Activator.CreateInstance(Type.GetType(dog)) as Animal;
string cat = "Cat";
var catObj = Activator.CreateInstance(Type.GetType(cat)) as Animal;
Console.WriteLine(dogObj);
Console.WriteLine(catObj);
}
}
public abstract class Animal
{
public override string ToString() { return "Type: " + GetType().Name; }
}
public class Cat : Animal
{
}
public class Dog : Animal
{
}
答案 2 :(得分:2)
另一种方法是使用属性标记您的类型,搜索所有这些标记的类型,然后根据所选的枚举值激活类型。
public enum ResourceType
{
Plant,
Rock,
Block
}
[AttributeUsage(AttributeTargets.Class, AllowMultiple=false, Inherited=false)]
public class ResourceDeclAttribute : Attribute
{
public ResourceDeclAttribute( ResourceType resType )
{
this.ResType = resType;
}
public ResourceType ResType { get; private set; }
}
public class Resource
{
// ...
}
[ResourceDecl( ResourceType.Plant )]
public class Plant : Resource
{
// ...
}
[ResourceDecl( ResourceType.Block )]
public class Block : Resource
{
// ...
}
[ResourceDecl( ResourceType.Rock )]
public class Rock : Resource
{
// ...
}
public class Loader
{
private Dictionary<ResourceType, Type> enumToTypeMap;
public Loader()
{
this.enumToTypeMap = new Dictionary<ResourceType, Type>();
}
public void Initialize()
{
Assembly targetAssembly;
// Fill in with the right way to identify your assembly. One trick is to have a dummy
// class in the assemblies that define your types, make a hard reference to those
// classes, and then use the class's types to find out what assembly they came from.
targetAssembly = Assembly.GetExecutingAssembly();
Type[] exportedTypes = targetAssembly.GetExportedTypes();
foreach( Type candidate in exportedTypes )
{
ResourceDeclAttribute attrib = candidate.GetCustomAttribute<ResourceDeclAttribute>();
if( attrib != null )
{
this.enumToTypeMap.Add( attrib.ResType, candidate );
}
}
}
public Resource Activate( ResourceType resType )
{
Type res = this.enumToTypeMap[resType];
return (Resource)Activator.CreateInstance( res );
}
}