【发布时间】:2018-06-22 08:20:08
【问题描述】:
将泛型类 T 存储在变量中并在子方法中重用它。
对于一个在少数对象上有杂物的 WebService:
Foo: Bar: Etc..
SetFoo SetBar SetEtc
GetFoo GetBar GetEtc
UpdateFoo UpdateBar UpdateEtc
DeleteFoo DeleteBar DeleteEtc
GetList .. ..
GetPending .. ..
Processed .. ..
我在客户端有以下单例通用包装器,方法如下:
public bool Get<T>(int i, out DloExtention result)
// DloExtention is an interface implemented by foo, bar, etc..
{
result = null;
try
{
if (typeof(T) == typeof(Foo))
{
result = WebserviceClient.GetFoo(i);
}
else if (typeof(T) == typeof(Bar))
{
result = WebserviceClient.GetBar(i);
}
else if (typeof(T) == typeof(Etc))
{
result = WebserviceClient.GetEtc(i);
}
else
{
throw new NotSupportedException("Get<T>, T is not a supported type.");
}
}
catch (Exception ex)
{
Log4N.Logger.Error($"Error in Namespace.ClientSide.Get<{nameof(T)}>(int {i} ). " + ex.Message);
return false;
}
return true;
}
所以我可以用同一个通用对象简单地处理所有类型:
class Processor
{
HashSet<int> validOperation = new HashSet<int>();
HashSet<int> invalidOperation = new HashSet<int>();
internal void Run<T>()
{
if (Wrapper.Instance.GetListPending<T>(out int[] newEntityList) && newEntityList.Any())
{
ProcessEntities<T>(newEntityList, false);
}
}
private void ProcessEntities<T>(int[] idsEnt, bool singleMode)
{
foreach (var idEnt in idsEnt)
{
ProcessEntity<T>(idEnt, false);
}
CloseValidOperation();
RemoveInvalidOperation();
}
internal void ProcessIncident<T>(int idEnt)
{
if (Wrapper.Instance.Get<T>(idEnt, out LanDataExchangeCore.LanDataExchangeWCF.DloExtention currentEntity))
{
if (currentEntity.isValid() && currentEntity.toLocalDB())
{
validOperation.Add(idEnt);
}
else
{
invalidOperation.Add(idEnt);
}
}
}
只有Wrapper.Instance.Get<T> 和Wrapper.Instance.GetListPending<T> 需要泛型参数。
但是每个方法都需要使用它才能将<T> 传递给最后一个方法。
有没有办法将Run<T> 调用中的<T> 保存到私有变量中,以便类的内部方法可以使用它?
我尝试添加Type myType;,但找不到在通用调用中使用它的方法。 Wrapper.Instance.Get<T> 的示例
Type myType; // class property
var fooWrapperGet = typeof(Wrapper).GetMethod("Get");
var fooOfMyTypeMethod = fooWrapperGet.MakeGenericMethod(new[] { myType });
//fooOfMyTypeMethod.Invoke(Wrapper.Instance , new object[] { new myType() });
// fooWrapperGet, as my wrapper is a singleton, Wrapper dont exposed Get<T>, but Wrapper.instance will expose it.
// new myType() <- do not compile.
【问题讨论】:
-
如果你需要在不同的函数中使用相同的类型,为什么不让你的类通用(而不是你的方法)?
-
@Freggar,好吧,因为在我的脑海中,该类的同一个实例将针对不同的类型进行处理,例如
myObj.Run<foo>(); myObj.Run<bar>(); myObj.Run<etc..>();。但是,是的,我可以简单地做到这一点。 -
我真的很讨厌星期五。 @Freggar,您选择如何获得满足:要么发布答案,要么您认为这是一个愚蠢无用的 x/y,我将其删除。
-
我希望您在回答您的实际问题时接受@Enigmativity 的回答。我的建议将要求您几乎完全重构您的代码,所以我不认为答案会公正地解决这个问题。
标签: c#