我有一系列的类,每个类都有不同的属性,每个类都有一个ID(每个类型不是每个实例)。
鉴于以下内容:
public class TestEntity : EntityBase {
public override ushort ID { get; } = 1;
public override void something() { do_something(); }
}
public class OtherEntity : EntityBase {
public override ushort ID { get; } = 2;
public override void something() { something_else(); }
}
在阅读数据时,我只有ushort
:
ushort EntityId = BitConverter.ToUInt16(data.GetRange(CURRENT_POSITION + TILE_ENTITY_ID_OFFSET, TILE_ENTITY_ID_LENGTH).ToArray().Reverse().ToArray(), 0);
如何使用EntityId
的值根据其值创建不同类型的对象?使用if
或switch
语句不是一种选择,因为将有超过200种类型。
答案 0 :(得分:8)
如果我理解你的问题,可以采取一种方法(有许多方法)。
private static Dictionary<ushort, Type> TypeMap = new Dictionary<ushort, Type>()
{
{ 1, typeof(TestEntity) },
{ 2, typeof(OtherEntity) }
};
private EntityBase CreateEntity(ushort id)
{
var type = TypeMap[id];
return (EntityBase) Activator.CreateInstance(type);
}
答案 1 :(得分:3)
最好的方法是定义一个包含ID属性的Attribute-Subclass,然后使用为每种类型提供唯一ID的属性注释所有类型。
Layter您可以收集并过滤包含给定属性的加载类型,并按属性的ID属性进行过滤
使用这种方法,您可以在以后添加其他子类型,而无需修改使用代码
实现可能如下所示:
public sealed class MyCustomAttribute : Attribute
{
public ushort Id { get; set; }
public MyCustomAttribute(ushort id)
{
this.Id = id;
}
}
public class MyDemoConsumer
{
public void MyConsumingMethod(ushort requiredTypeId)
{
var requestedType = AppDomain
.CurrentDomain
.GetAssemblies()
.SelectMany(asm => asm.GetTypes())
.Where(type => type.GetCustomAttributes(typeof(MyCustomAttribute), false).Any())
.Select(type => new { Type = type, CustomId = type.GetCustomAttributes(typeof(MyCustomAttribute), false).Cast<MyCustomAttribute>().Single().Id })
.Where(item => item.CustomId == requiredTypeId)
.Select(item => item.Type)
.SingleOrDefault();
if (requestedType != null)
{
var result = Activator.CreateInstance(requestedType);
}
}
}
答案 2 :(得分:3)
......有很多方法可以做到这一点,但这里很简单...
class Program
{
static void Main()
{
var simpleFactory = new SimpleFactory();
var entity = simpleFactory.Create(1);
entity.Something();
}
}
public abstract class EntityBase
{
public abstract ushort ID { get; }
public abstract void Something();
}
public class TestEntity : EntityBase
{
public override ushort ID { get { return 1; } }
public override void something() { }
}
public class OtherEntity : EntityBase
{
public override ushort ID { get { return 2; } }
public override void something() { }
}
public class SimpleFactory
{
private Dictionary<ushort, Func<EntityBase>> config = new Dictionary<ushort, Func<EntityBase>>
{
{ 1, ()=>new TestEntity()},
{ 2, ()=>new OtherEntity()},
};
public EntityBase Create(ushort entityId)
{
if (!config.ContainsKey(entityId))
throw new InvalidOperationException();
return config[entityId]();
}
}