返回一个列表<;类型>;使用动态选择的类型,同时强制转换为该类型(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
。