我编写了以下代码片段:
public interface IModelToViewModelServiceBase<in TDomain, out TViewModel>
where TDomain : class, IDataModel
where TViewModel : class, IDataModelViewModel
{
TViewModel GetViewModel(TDomain model);
}
public abstract class ModelToViewModelServiceBase<TDomain, TViewModel> : IModelToViewModelServiceBase<TDomain, TViewModel>
where TDomain : class, IDataModel
where TViewModel : class, IDataModelViewModel
{
private readonly IDictionary<TDomain, TViewModel> _modelToViewModel
= new Dictionary<TDomain, TViewModel>();
protected abstract TViewModel Create(TDomain model);
public TViewModel GetViewModel(TDomain model)
{
if (model == null) return null;
if (!_modelToViewModel.ContainsKey(model))
_modelToViewModel[model] = Create(model);
return _modelToViewModel[model];
}
}
此类的目的与问题无关。在极少数情况下,我会在返回线上得到 KeyNotFound。但是,据我了解,前面的 if 子句应该可以防止这种情况发生。没有键可能为空,如果之前不存在,则在上一条指令中添加检索到的值。
我在这里想念什么?
我现在开发了一个解决方法:
public interface IModelToViewModelServiceBase<in TDomain, out TViewModel>
where TDomain : class, IDataModel
where TViewModel : class, IDataModelViewModel
{
TViewModel GetViewModel(TDomain model);
}
public abstract class ModelToViewModelServiceBase<TDomain, TViewModel> : IModelToViewModelServiceBase<TDomain, TViewModel>
where TDomain : class, IDataModel
where TViewModel : class, IDataModelViewModel
{
private readonly IDictionary<TDomain, TViewModel> _modelToViewModel
= new Dictionary<TDomain, TViewModel>();
protected abstract TViewModel Create(TDomain model);
public TViewModel GetViewModel(TDomain model)
{
if (model == null) return null;
TViewModel viewModel = null;
if (!_modelToViewModel.ContainsKey(model))
{
viewModel = Create(model);
_modelToViewModel[model] = viewModel;
}
else
viewModel = _modelToViewModel[model];
return viewModel;
}
}
这似乎有效。但是,这种解决方法应该不是必需的。可能这种解决方法更好,因为现在执行的对字典的访问减少了。尽管如此,以前的版本应该一直有效。
回答后更新:
@evk 和@mjwills 都是对的。我不认为我的代码对于并发使用是不安全的,并且多个线程正在访问它。因此,根据@mjwills 的建议,代码如下所示:
public interface IModelToViewModelServiceBase<in TDomain, out TViewModel>
where TDomain : class, IDataModel
where TViewModel : class, IDataModelViewModel
{
TViewModel GetViewModel(TDomain model);
}
public abstract class ModelToViewModelServiceBase<TDomain, TViewModel> : IModelToViewModelServiceBase<TDomain, TViewModel>
where TDomain : class, IDataModel
where TViewModel : class, IDataModelViewModel
{
private readonly ConcurrentDictionary<TDomain, TViewModel> _modelToViewModel
= new ConcurrentDictionary<TDomain, TViewModel>();
protected abstract TViewModel Create(TDomain model);
public TViewModel GetViewModel(TDomain model)
{
if (model == null) return null;
return _modelToViewModel.GetOrAdd(model, Create); ;
}
}