将对象显式强制转换为 C# 中仅在运行时可用的泛型类型的另一个对象
本文关键字:运行时 泛型类型 一个对象 对象 转换 | 更新日期: 2023-09-27 18:36:56
我正在尝试将某种类型转换为另一种泛型类型,但我找不到任何解决方案来说明在我的特定情况下如何做到这一点。简化情况如下。请注意,这可能看起来很奇怪和人为,但这只是为了指出我的问题。实际的应用程序更有意义... :-)
// Raw data coming from some source
public class RawDataType { }
// Abstract base class for structured data representing this raw data
public abstract class AbstractListDataType { }
// Generates lists of structured data
public class ListGenerator<TListDataType> where TListDataType : AbstractListDataType
{
public List<TListDataType> GenerateList()
{
// Get the data from some mysterious place
RawDataType data = new RawDataType() { ... }
// Cast it to the required structured data type
return new List<TListDataType>() { data as TListDataType ??? }
}
}
然后在运行时加载的另一个程序集中,此原始数据有一些具体的表示形式。ListGenerator本身对这些类型完全不了解。加载包含结构化数据类型的程序集后,将使用反射对其进行检查,以查看可以生成哪些类型的结构化数据。
// Two types of structured application data that can be created from the raw data
public class ListDataTypeA : AbstractListDataType
{
public static explicit operator ListDataTypeA(RawDataType data) { ... }
}
public class ListDataTypeB : AbstractListDataType
{
public static explicit operator ListDataTypeB(RawDataType data) { ... }
}
答案是肯定的
data as TListDataType
没有意义。如何实现从 RawDataType 到 ListDataTypeA 的动态强制转换,我知道有一个显式转换可用,但仅在运行时可用?
编辑:
似乎以下工作:
(TListDataType)(dynamic)data
我觉得这非常丑陋。考虑到我在这里描述的情况,有没有更好的方法?
如果dynamic
方法不适合您 - 请尝试更标准的工厂模式。
由于显式强制转换是在编译时解析的,因此您必须自己手动调用该方法(即通过反射)。
我会走另一条路线,将"Load"方法添加到AbstractListDataType
或使用工厂方法/类来创建所需类的项目:
public abstract class AbstractListDataType {
public void Load(RawData data)....
}
public class ListGenerator<TListDataType>
where TListDataType : AbstractListDataType, new()
public List<TListDataType> GenerateList()
{
RawDataType data = new RawDataType() { ... }
var item = new T();
item.Load(data);
return new List<TListDataType>() { item };
}
}
或工厂方法:
public abstract class ListItemFactory<T>
{
abstract public T CreateFromRawData(RawDataType data);
}
public class ListGenerator<TListDataType>
where TListDataType : AbstractListDataType
{
ListItemFactory<TListDataType> factory;
public ListGenerator<TListDataType>(ListItemFactory<TListDataType> factory)
{
this.factory = factory;
}
public List<TListDataType> GenerateList()
{
RawDataType data = new RawDataType() { ... }
return new List<TListDataType>() { factory.CreateFromRawData(data)};
}
}