创建从 ToDictionary() 派生的扩展方法
Create an extension method derived from ToDictionary()
我想创建一个派生自 ToDictionary()
的扩展方法。目前为了达到预期的结果,我这样做:
ObjectAttributes = model.ObjectAttributes.ToDictionary(
oa => oa.Attribute.Name, oa => oa.ToWrapper<ObjectAttributeWrapper>());
所以我使用以下 ToDictionary
签名:
public static Dictionary<TKey, TElement> ToDictionary<TSource, TKey, TElement>(
this IEnumerable<TSource> source,
Func<TSource, TKey> keySelector,
Func<TSource, TElement> elementSelector);
我想知道是否可以这样做?
ObjectAttributes = model.ObjectAttributes.ToDictionaryWrapper<ObjectAttributeWrapper>(
oa => oa.Attribute.Name);
这是当前的实现,但显然不起作用:
public static Dictionary<TKey, TWrapper> ToDictionaryWrapper<TWrapper, TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector) where TSource : BaseModel where TWrapper : IBaseWrapper
{
return source.ToDictionary(keySelector, model => model.ToWrapper<TWrapper>());
}
编辑:
ToWrapper()
的实施:
public static TWrapper ToWrapper<TWrapper>(this BaseModel model) where TWrapper : IBaseWrapper
{
if (model == null)
return default;
var type = typeof(TWrapper);
if (_wrapperParents.ContainsKey(type) && _wrapperParents[type].Id == model.Id)
return (TWrapper)_wrapperParents[type];
else
return (TWrapper)GetConstructor<TWrapper>().Invoke(new object[] { model });
}
public static IEnumerable<TWrapper> ToListWrapper<TWrapper>(this IEnumerable models) where TWrapper : IBaseWrapper
{
var _models = models as IEnumerable<BaseModel>;
if (_models == null)
return default;
return _models.Select(model => model.ToWrapper<TWrapper>());
}
通常,对于单个通用约束列表,您只能显式提供所有参数或自动解析所有参数。您不能部分提供约束。
所以你的选择如下(我假设 TWrapper
会有 属性 WrappedObject
):
- 按原样提供所有参数
- 减少通用参数的数量(如果键类型始终相同,您甚至可以将其设为非通用)
// signature
Dictionary<TKey, TWrapper> ToDictionaryWrapper<TWrapper, TKey>(
this IEnumerable<BaseModel> source,
Func<BaseModel, TKey> keySelector)
where TWrapper : IBaseWrapper;
// call
model.ObjectAttributes
.ToDictionaryWrapper<ObjectAttributeWrapper, string>(oa => oa.Attribute.Name);
- 将您的函数调用分成两部分,其中一部分是显式的,另一部分是隐式的
// signature
IEnumerable<TWrapper> Wrap<TWrapper>(this IEnumerable<BaseModel> source)
where TWrapper : IBaseWrapper;
Dictionary<TKey, TWrapper> ToDictionaryWrapper<TWrapper, TKey>(
this IEnumerable<TWrapper> source,
Func<BaseModel, TKey> keySelector)
where TWrapper : IBaseWrapper;
// call
model.ObjectAttributes
.Wrap<ObjectAttributeWrapper>()
.ToDictionaryWrapper(oa => oa.Attribute.Name);
- 不用担心自定义
ToDictionaryWrapper
,只需使用 Wrap-Function 和框架 ToDictionary
// call (signature for Wrap same as above)
model.ObjectAttributes
.Wrap<ObjectAttributeWrapper>()
.ToDictionary(w => w.WrappedObject.Attribute.Name);
我想创建一个派生自 ToDictionary()
的扩展方法。目前为了达到预期的结果,我这样做:
ObjectAttributes = model.ObjectAttributes.ToDictionary(
oa => oa.Attribute.Name, oa => oa.ToWrapper<ObjectAttributeWrapper>());
所以我使用以下 ToDictionary
签名:
public static Dictionary<TKey, TElement> ToDictionary<TSource, TKey, TElement>(
this IEnumerable<TSource> source,
Func<TSource, TKey> keySelector,
Func<TSource, TElement> elementSelector);
我想知道是否可以这样做?
ObjectAttributes = model.ObjectAttributes.ToDictionaryWrapper<ObjectAttributeWrapper>(
oa => oa.Attribute.Name);
这是当前的实现,但显然不起作用:
public static Dictionary<TKey, TWrapper> ToDictionaryWrapper<TWrapper, TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector) where TSource : BaseModel where TWrapper : IBaseWrapper
{
return source.ToDictionary(keySelector, model => model.ToWrapper<TWrapper>());
}
编辑:
ToWrapper()
的实施:
public static TWrapper ToWrapper<TWrapper>(this BaseModel model) where TWrapper : IBaseWrapper
{
if (model == null)
return default;
var type = typeof(TWrapper);
if (_wrapperParents.ContainsKey(type) && _wrapperParents[type].Id == model.Id)
return (TWrapper)_wrapperParents[type];
else
return (TWrapper)GetConstructor<TWrapper>().Invoke(new object[] { model });
}
public static IEnumerable<TWrapper> ToListWrapper<TWrapper>(this IEnumerable models) where TWrapper : IBaseWrapper
{
var _models = models as IEnumerable<BaseModel>;
if (_models == null)
return default;
return _models.Select(model => model.ToWrapper<TWrapper>());
}
通常,对于单个通用约束列表,您只能显式提供所有参数或自动解析所有参数。您不能部分提供约束。
所以你的选择如下(我假设 TWrapper
会有 属性 WrappedObject
):
- 按原样提供所有参数
- 减少通用参数的数量(如果键类型始终相同,您甚至可以将其设为非通用)
// signature
Dictionary<TKey, TWrapper> ToDictionaryWrapper<TWrapper, TKey>(
this IEnumerable<BaseModel> source,
Func<BaseModel, TKey> keySelector)
where TWrapper : IBaseWrapper;
// call
model.ObjectAttributes
.ToDictionaryWrapper<ObjectAttributeWrapper, string>(oa => oa.Attribute.Name);
- 将您的函数调用分成两部分,其中一部分是显式的,另一部分是隐式的
// signature
IEnumerable<TWrapper> Wrap<TWrapper>(this IEnumerable<BaseModel> source)
where TWrapper : IBaseWrapper;
Dictionary<TKey, TWrapper> ToDictionaryWrapper<TWrapper, TKey>(
this IEnumerable<TWrapper> source,
Func<BaseModel, TKey> keySelector)
where TWrapper : IBaseWrapper;
// call
model.ObjectAttributes
.Wrap<ObjectAttributeWrapper>()
.ToDictionaryWrapper(oa => oa.Attribute.Name);
- 不用担心自定义
ToDictionaryWrapper
,只需使用 Wrap-Function 和框架ToDictionary
// call (signature for Wrap same as above)
model.ObjectAttributes
.Wrap<ObjectAttributeWrapper>()
.ToDictionary(w => w.WrappedObject.Attribute.Name);