在 C# 中,如何创建需要访问多个列表类型的可重用方法?
In C#, how can I create a reusable method where I need to access multiple list types?
我有以下两种方法:
private void AddHeaderAttachment(AAttachment attachment) {
string parentId = attachment.ParentId;
if (this.collectionByIds.TryGetValue(attachment.Id, out MyCollection collection)) {
if (!collection.AAttachmentByParentIds.TryGetValue(parentId, out List<AAttachment> attachmentList)) {
attachmentList = new List<AAttachment>();
collection.AAttachmentByParentIds.Add(parentId, attachmentList);
}
attachmentList.Add(attachment);
}
}
private void AddLineAttachment(BAttachment attachment) {
string parentId = attachment.ParentId;
if (this.collectionByIds.TryGetValue(attachment.Id, out MyCollection collection)) {
if (!collection.BAttachmentByParentIds.TryGetValue(parentId, out List<BAttachment> attachmentList)) {
attachmentList = new List<BAttachment>();
collection.BAttachmentByParentIds.Add(parentId, attachmentList);
}
attachmentList.Add(attachment);
}
}
class MyCollection
看起来像这样:
public class MyCollection {
public Dictionary<string, List<AAttachment>> AAttachmentByParentIds = new Dictionary<string, List<AAttachment>>();
public Dictionary<string, List<BAttachment>> BAttachmentByParentIds = new Dictionary<string, List<BAttachment>>();
}
如您所见,上述两种方法之间的唯一区别是:
- 提供的类型
MyCollection
的 属性 其中
附件将被添加到。
但是,AAttachment
和 BAttachment
都实现了:
interface Attachable {
string ParentId { get; }
}
我想创建一个可重复使用的方法。
但是我有两个明显的问题:
- 如果我将内部
if
更改为:
if (!collection.AAttachmentByParentIds.TryGetValue(parentId, out List<Attachable> attachmentList)) {
attachmentList = new List<Attachable>();
collection.lineAttachmentByParentIds.Add(parentId, attachmentList);
}
Visual Studio 通知我“参数 2:无法将 out List<Attachable>
转换为 out List<AttachmentA>
和
- 如何更改我在 MyCollection 实例上引用的是
AAttachmentByParentIds
还是 BAttachmentByParentIds
?
您是否尝试过使用 generics :
private void AddAttachable<T>(....) where T:Attachable
完整代码如下所示:
private void AddAttachable<T>(T attachment, Func<MyCollection, Dictionary<string,T>> getFunc)
where T:Attachable
{
string parentId = attachment.ParentId;
if (this.collectionByIds.TryGetValue(attachment.Id, out MyCollection collection)) {
// func is used here
if (!getFunc(collection).TryGetValue(parentId, out List<T> attachmentList)) {
attachmentList = new List<T>();
// and here, can be moved to variable
getFunc(collection).Add(parentId, attachmentList);
}
attachmentList.Add(attachment);
}
}
和用法
BAttachment bAttach = ...
AddAttachment(bAttach, col => col.BAttachmentByParentIds )
您想使用泛型:
private void AddHeaderAttachment<TAttachment>(
Func<MyCollection, Dictionary<string, List<TAttachment>>> attachmentByParentIdsSelector,
TAttachment attachment) where TAttachment : Attachable
{
string parentId = attachment.ParentId;
if (this.collectionByIds.TryGetValue(attachment.Id, out MyCollection collection))
{
var attachmentByParentIds = attachmentByParentIdsSelector(collection);
if (!attachmentByParentIds.TryGetValue(parentId, out List<TAttachment> attachmentList))
{
attachmentList = new List<TAttachment>();
attachmentByParentIds.Add(parentId, attachmentList);
}
attachmentList.Add(attachment);
}
}
private void AddHeaderAttachment(AAttachment attachment)
{
AddHeaderAttachment(x => x.AAttachmentByParentIds, attachment);
}
private void AddHeaderAttachment(BAttachment attachment)
{
AddHeaderAttachment(x => x.BAttachmentByParentIds, attachment);
}
我有以下两种方法:
private void AddHeaderAttachment(AAttachment attachment) {
string parentId = attachment.ParentId;
if (this.collectionByIds.TryGetValue(attachment.Id, out MyCollection collection)) {
if (!collection.AAttachmentByParentIds.TryGetValue(parentId, out List<AAttachment> attachmentList)) {
attachmentList = new List<AAttachment>();
collection.AAttachmentByParentIds.Add(parentId, attachmentList);
}
attachmentList.Add(attachment);
}
}
private void AddLineAttachment(BAttachment attachment) {
string parentId = attachment.ParentId;
if (this.collectionByIds.TryGetValue(attachment.Id, out MyCollection collection)) {
if (!collection.BAttachmentByParentIds.TryGetValue(parentId, out List<BAttachment> attachmentList)) {
attachmentList = new List<BAttachment>();
collection.BAttachmentByParentIds.Add(parentId, attachmentList);
}
attachmentList.Add(attachment);
}
}
class MyCollection
看起来像这样:
public class MyCollection {
public Dictionary<string, List<AAttachment>> AAttachmentByParentIds = new Dictionary<string, List<AAttachment>>();
public Dictionary<string, List<BAttachment>> BAttachmentByParentIds = new Dictionary<string, List<BAttachment>>();
}
如您所见,上述两种方法之间的唯一区别是:
- 提供的类型
MyCollection
的 属性 其中 附件将被添加到。
但是,AAttachment
和 BAttachment
都实现了:
interface Attachable {
string ParentId { get; }
}
我想创建一个可重复使用的方法。
但是我有两个明显的问题:
- 如果我将内部
if
更改为:
if (!collection.AAttachmentByParentIds.TryGetValue(parentId, out List<Attachable> attachmentList)) {
attachmentList = new List<Attachable>();
collection.lineAttachmentByParentIds.Add(parentId, attachmentList);
}
Visual Studio 通知我“参数 2:无法将 out List<Attachable>
转换为 out List<AttachmentA>
和
- 如何更改我在 MyCollection 实例上引用的是
AAttachmentByParentIds
还是BAttachmentByParentIds
?
您是否尝试过使用 generics :
private void AddAttachable<T>(....) where T:Attachable
完整代码如下所示:
private void AddAttachable<T>(T attachment, Func<MyCollection, Dictionary<string,T>> getFunc)
where T:Attachable
{
string parentId = attachment.ParentId;
if (this.collectionByIds.TryGetValue(attachment.Id, out MyCollection collection)) {
// func is used here
if (!getFunc(collection).TryGetValue(parentId, out List<T> attachmentList)) {
attachmentList = new List<T>();
// and here, can be moved to variable
getFunc(collection).Add(parentId, attachmentList);
}
attachmentList.Add(attachment);
}
}
和用法
BAttachment bAttach = ...
AddAttachment(bAttach, col => col.BAttachmentByParentIds )
您想使用泛型:
private void AddHeaderAttachment<TAttachment>(
Func<MyCollection, Dictionary<string, List<TAttachment>>> attachmentByParentIdsSelector,
TAttachment attachment) where TAttachment : Attachable
{
string parentId = attachment.ParentId;
if (this.collectionByIds.TryGetValue(attachment.Id, out MyCollection collection))
{
var attachmentByParentIds = attachmentByParentIdsSelector(collection);
if (!attachmentByParentIds.TryGetValue(parentId, out List<TAttachment> attachmentList))
{
attachmentList = new List<TAttachment>();
attachmentByParentIds.Add(parentId, attachmentList);
}
attachmentList.Add(attachment);
}
}
private void AddHeaderAttachment(AAttachment attachment)
{
AddHeaderAttachment(x => x.AAttachmentByParentIds, attachment);
}
private void AddHeaderAttachment(BAttachment attachment)
{
AddHeaderAttachment(x => x.BAttachmentByParentIds, attachment);
}