返回一个列表<;类型>;使用动态选择的类型,同时强制转换为该类型(C#)

返回一个列表<;类型>;使用动态选择的类型,同时强制转换为该类型(C#),c#,casting,system.reflection,C#,Casting,System.reflection,已解决,请参阅文章末尾的解决方案 我有一个返回附件列表的方法。我有三种类型的附件,它们都扩展了一个名为genericatachment的类: GenericAttachment || ==> FormA_Attachment ==> FormB_Attachment ==> FormC_Attachment 我还有不同的表单类型,它们都扩展了一个名为GenericForm的类: GenericForm || ==> FormA ==> FormB ==>

已解决,请参阅文章末尾的解决方案


我有一个返回附件列表的方法。我有三种类型的附件,它们都扩展了一个名为
genericatachment
的类:

GenericAttachment
||
==> FormA_Attachment
==> FormB_Attachment
==> FormC_Attachment
我还有不同的表单类型,它们都扩展了一个名为
GenericForm
的类:

GenericForm
||
==> FormA
==> FormB
==> FormC
该方法必须采用FormA、FormB或FormC的
类型
参数,并返回相应类型的附件

我先试过这个:

public static List<GenericAttachment> GetAllAttachmentsByFormID<T>(int sqlFormId, Type type) where T : GenericForm
{
        //this returns e.g. FormA_Attachment based on FormA as the input
        Type attachmentType = GetAttachmentTypeByFormType(type);

        //Call a generic function (overload of this one) 
        //that returns all attachments and requires a specific type argument.
        //Meanwhile, .Invoke()'s return type is just an `object`
        var attachments = typeof(AttachmentManager)
                              .GetMethod("GetAllAttachmentsByFormID", new[] { typeof(int) }) // select the correct overload for the method
                              .MakeGenericMethod(attachmentType)
                              .Invoke(new AttachmentManager(), new object[] { sqlFormId });

        return (List<GenericAttachment>)attachments;
}
如何将
附件
强制转换为
列表
,在该列表中动态选择
类型


解决方案

感谢@Mikhail Neofitov,下面的代码工作正常

附件
的类型为
对象
,因为这是
.Invoke()
返回的

因此,我首先将其转换为特定类型,然后使用
.OfType().ToList()
将其转换为不太特定的类型

if(附件类型==typeof(格式附件))
{
return((List)Convert.ChangeType(附件,typeof(List))).OfType().ToList();
}
else if(attachmentType==typeof(FormB_附件))
... 
//相似代码
C#不允许,这意味着
List
无法简单地转换为
List

        if (attachmentType == typeof(FormA_Attachment))
        {
            return ((List<FormA_Attachment>) Convert.ChangeType(attachments, typeof(List<FormA_Attachment>))).OfType<GenericAttachment>().ToList();
        }
        else if (attachmentType == typeof(FormB_Attachment))
        ... 
        //similar code
在您的情况下,您可以使用
LINQ
扩展方法,如下所示:

return attachments.OfType<GenericAttachment>().ToList();
return ((IEnumerable<GenericAttachment>)attachments).ToList();
返回attachments.OfType().ToList();
请注意,我想,您可以修改应用程序架构,将结果类型
genericalargument
传递给
GenericForm
的generic参数,并定义一个抽象方法,用于在结果类型中返回结果附件。另外,您的泛型参数
是无用的,您不能在方法体中使用它。

C不允许,这意味着
List
不能简单地转换为
List

        if (attachmentType == typeof(FormA_Attachment))
        {
            return ((List<FormA_Attachment>) Convert.ChangeType(attachments, typeof(List<FormA_Attachment>))).OfType<GenericAttachment>().ToList();
        }
        else if (attachmentType == typeof(FormB_Attachment))
        ... 
        //similar code
在您的情况下,您可以使用
LINQ
扩展方法,如下所示:

return attachments.OfType<GenericAttachment>().ToList();
return ((IEnumerable<GenericAttachment>)attachments).ToList();
返回attachments.OfType().ToList();
请注意,我想,您可以修改应用程序架构,将结果类型
genericalargument
传递给
GenericForm
的generic参数,并定义一个抽象方法,用于在结果类型中返回结果附件。另外,您的泛型参数
是无用的,您不会在方法体中使用它。

请查看。这是一个将
列表
转换为
列表

的高效内存示例。请看。这是一个将
列表
转换为
列表

的高效内存示例。您可以在此处利用协方差<代码>列表不是变量,但它实现了t中协变的
IEnumerable
。这意味着您不能将
对象
转换为
列表
,但可以将其转换为
IEnumerable
。因此,您应该能够执行以下操作,而不是所有这些
if
s:

return attachments.OfType<GenericAttachment>().ToList();
return ((IEnumerable<GenericAttachment>)attachments).ToList();
返回((IEnumerable)附件).ToList();
您可以在此处利用协方差<代码>列表不是变量,但它实现了t中协变的
IEnumerable
。这意味着您不能将
对象
转换为
列表
,但可以将其转换为
IEnumerable
。因此,您应该能够执行以下操作,而不是所有这些
if
s:

return attachments.OfType<GenericAttachment>().ToList();
return ((IEnumerable<GenericAttachment>)attachments).ToList();
返回((IEnumerable)附件).ToList();

need?@LeiYang我正在尝试
return(List)Convert.ChangeType(附件,typeof(List))但是它说无法将列表隐式转换为列表。添加另一个类型参数TResult如何?我无法将此参数传递给该方法,必须在运行时确定确切的返回类型。我只知道该方法将返回扩展
generictachment
的类型之一。仅仅因为
FormA_Attachment
继承自
generictachment
并不意味着
List
继承自
List
。需要吗?@LeiYang我正在尝试
return(List)Convert.ChangeType(附件,typeof(列表));
但上面写着"无法隐式地将列表转换为列表。添加另一个类型参数TResult如何?我无法将此参数传递给该方法,必须在运行时确定确切的返回类型。我只知道该方法将返回扩展
genericatachment
的类型之一。这只是因为
FormA_Attachment
继承自
Gener>icAttachment
并不意味着
List
继承自
List