从具有共享函数的泛型类调用函数的最佳方法是什么



我正在试图找出调用泛型类的函数的最佳方法。<罢工>

public T Create<T>(T obj)
{
switch (obj.GetType().Name)
{
case "Bank":
(new Bank()).Create(obj);
break;
case "Bar":
(new Bar()).Create(obj);
break;
case "Beer":
(new Beer()).Create(obj);
break;
default:
(new Broke()).Create(obj);
break;
}
return obj;
}

我有大约30个类,所以这将是一个非常丑陋的大开关语句,很难管理,我必须传递大约100,000个obj。而且这是CRUD,所以我要做4次。反射有点慢。到目前为止,我一直坐在办公桌前,满脸愁容,试图想出一个好办法。我问了我的好朋友Alexa, Siri和谷歌,但他们并没有那么有帮助。通常我能从其中一个人那里得到我需要的所有答案。

2天后

我当时没有很好地解释。但我还是选择了巨大的开关,简化后的版本是这样的。通过重载CreateEntity函数接受每个不同的类

public Entry Create<T>(T obj, ObjBuilder builder)
{
Entry entry;
switch (obj)
{
case Profile p:
entry = builder.CreateEntity(p);
break;
case Area a:
entry = builder.CreateEntity(a);
break;
case Credential c:
entry = builder.CreateEntity(c);
break;
case Device d:
entry = builder.CreateEntity(d);
break;
}
return entry;
}
<代码>

我建议您考虑使用CC_2来完成此工作。这看起来可能很复杂,但它使您能够在运行时添加任意数量的类型。

代码如下:

Register<Profile>((b, x) => b.CreateEntity(x));
Register<Area>((b, x) => b.CreateEntity(x));
Register<Credential>((b, x) => b.CreateEntity(x));
Register<Device>((b, x) => b.CreateEntity(x));

现在注册你的工厂:

private Dictionary<Type, Delegate> _creators = new Dictionary<Type, Delegate>()
{
{ typeof(Profile), (Func<ObjBuilder, Profile, Entry>)((b, x) => b.CreateEntity(x)) },
{ typeof(Area), (Func<ObjBuilder, Area, Entry>)((b, x) => b.CreateEntity(x)) },
{ typeof(Credential), (Func<ObjBuilder, Credential, Entry>)((b, x) => b.CreateEntity(x)) },
{ typeof(Device), (Func<ObjBuilder, Device, Entry>)((b, x) => b.CreateEntity(x)) },
};

容易。

或者你可以像这样硬编码字典:

void Main()
{
Register<Bank>(obj => (new Bank()).Create(obj));
Register<Bar>(obj => (new Bar()).Create(obj));
Register<Beer>(obj => (new Beer()).Create(obj));
Register<Broke>(obj => (new Broke()).Create(obj));
}
private Dictionary<Type, Delegate> _creators = new Dictionary<Type, Delegate>();
public T Create<T>(T obj)
{
if (_creators.ContainsKey(typeof(T)))
{
((Func<T, T>)_creators[typeof(T)])(obj);
}
return obj;
}
public void Register<T>(Action<T> action)
{
_creators[typeof(T)] = action;
}

或者两者都可以


下面是对原始代码的处理方法:

public interface ICreateable<T> {
T Create();
}
public class Bank : ICreateable<Bank> {
public Bank Create()
{
return new Bank();
}
// ...
}

一个简单的解决方案是让所有实体实现相同的接口。

public class EntryData
{
int X { get; }
int Y { get; }
}
public interface IEntryData {
EntryData GetEntryData();
}
public class Profile: IEntryData {
...
public EntryData AsEntry();
}

public class Area: IEntryData {
...
public EntryData AsEntry();
}
...
Option 1:
public Entry Create(object obj, ObjBuilder builder) {
if(obj is not IEntryData) {...}

IEntryData entryData = obj as IEntryData;
builder.CreateEntity(entryData);
}
Option 2: 
public Entry Create(IEntryData obj, ObjBuilder builder)  
=> builder.CreateEntity(entryData);
...
class ObjBuilder {
Entry CreateEntity(IEntryData entryData) {
// Other things
var extra = ...
return new Entry(
x: entryData.X,
y: entryData.Y,
z: extra.Z)
}

不太确定用例是什么。

你能试着用下面的方法来分析这个问题吗?

PP_9

最新更新