在C#和反射中从接口类型转换为具体类型
Hi有几个实现一个接口的类。我想将ILoad列表中的项转换为its的具体类,就像这样。我想调用工厂转换器来获得另一个类型在C#和反射中从接口类型转换为具体类型,c#,reflection,C#,Reflection,Hi有几个实现一个接口的类。我想将ILoad列表中的项转换为its的具体类,就像这样。我想调用工厂转换器来获得另一个类型 List<ILoad> list = new List<ILoad>(); list = GetALlIloads(); Factory f = new Factory(); foreach (var item in list) { var typeOfObject = item.GetTy
List<ILoad> list = new List<ILoad>();
list = GetALlIloads();
Factory f = new Factory();
foreach (var item in list)
{
var typeOfObject = item.GetType();
var concreteType = **(typeOfObject)**item;
var converted = f.ConvertToMeasure(concreteType );
}
public class A: Iload
{
// something
}
publicclass B: ILoad
{
//Something
}
public class Factory
{
public List<Measure> ConvertToMeausre(A model)
{
return some List<Measure>
}
public List<Measure> ConvertToMeausre(B model)
{
return some List<Measure>
}
}
List List=新列表();
list=GetALlIloads();
工厂f=新工厂();
foreach(列表中的变量项)
{
var typeOfObject=item.GetType();
变量concreteType=**(typeOfObject)**项;
转换后的var=f.ConvertToMeasure(混凝土类型);
}
公共A级:Iload
{
//某物
}
B类:ILoad
{
//某物
}
公营工厂
{
公共列表转换器(A型)
{
返回一些列表
}
公共列表转换器(B型)
{
返回一些列表
}
}
我将把ConvertToMeasure移到您的界面上
interface ILoad {
List<Measure> ConvertToMeasure();
}
class A : ILoad {
public string PropA { get; set; }
public List<Measure> ConvertToMeasure()
{
throw new NotImplementedException();
}
}
class B : ILoad {
public string PropB { get; set; }
public List<Measure> ConvertToMeasure()
{
throw new NotImplementedException();
}
}
接口ILoad{
列表ConvertToMeasure();
}
A类:ILoad{
公共字符串PropA{get;set;}
公共列表转换度量()
{
抛出新的NotImplementedException();
}
}
B类:ILoad{
公共字符串PropB{get;set;}
公共列表转换度量()
{
抛出新的NotImplementedException();
}
}
然后您可以正常访问这些类:
List<ILoad> list = new List<ILoad>();
var s = new A();
list.Add(new A() { PropA = "test1" });
list.Add(new B() { PropB = "test2" });
list.Add(new A() { PropA = "test3" });
foreach (var item in list)
{
item.ConvertToMeasure();
}
List List=新列表();
var s=新的A();
添加(新的A(){PropA=“test1”});
添加(新的B(){PropB=“test2”});
添加(新的A(){PropA=“test3”});
foreach(列表中的变量项)
{
项。转换测量();
}
您可以这样做吗?在您的例子中,您可以将所有与类型反射相关的代码放入一个特殊函数中,该函数接受
ILoad
,并进一步处理它:
public class Factory
{
public IList<Measure> ConvertToMeasures(ILoad load)
{
if (load == null)
throw new NullArgumentException("load");
if (load is A)
return ConvertToMeausre((A)load);
if (load is B)
return ConvertToMeausre((B)load);
throw new NotSupportedException();
}
public List<Measure> ConvertToMeausre(A model)
{
return some List<Measure>
}
public List<Measure> ConvertToMeausre(B model)
{
return some List<Measure>
}
}
这不是最好的解决方案,但是如果您已经将具体类型降级为接口,并且无法更改它们,那么这是最简单的解决方案
当然,更像OOP的解决方案是修改
ILoad
接口,但正如您所说的,这是不可能的。尽管如此,如果这将大大简化使用场景,您可以为每个ILoad实现者创建自己的扩展接口和特定包装器:
public interface ILoadExt: ILoad
{
IList<Measure> ConvertToMeasure();
}
public class AExt : A, ILoadExt
{
public List<Measure> ConvertToMeasure()
{
return some List<Measure>
}
}
public class BExt : B, ILoadExt
{
public List<Measure> ConvertToMeasure()
{
return some List<Measure>
}
}
公共接口ILoadExt:ILoad
{
IList ConvertToMeasure();
}
公共类AExt:A,ILoadExt
{
公共列表转换度量()
{
返回一些列表
}
}
公共类BExt:B,ILoadExt
{
公共列表转换度量()
{
返回一些列表
}
}
并在收到物品时进行包装:
var load = new BExt(factory.GetB());
IList<ILoadExt> loads = new List<ILoadExt>();
loads.Add(load);
var load=newbext(factory.GetB());
IList loads=新列表();
加载。添加(加载);
您可以使用这样的类型
List<ILoad> list = new List<ILoad>();
list = GetALlIloads();
Factory f = new Factory();
foreach (var item in list)
{
dynamic concreteType = item;
var converted = f.ConvertToMeasure(concreteType);
}
public class A: Iload
{
// something
}
public class B: ILoad
{
//Something
}
public class Factory
{
public List<Measure> ConvertToMeausre(A model)
{
return some List<Measure>
}
public List<Measure> ConvertToMeausre(B model)
{
return some List<Measure>
}
}
List List=新列表();
list=GetALlIloads();
工厂f=新工厂();
foreach(列表中的变量项)
{
动态混凝土类型=项目;
转换后的var=f.ConvertToMeasure(混凝土类型);
}
公共A级:Iload
{
//某物
}
公共B类:ILoad
{
//某物
}
公营工厂
{
公共列表转换器(A型)
{
返回一些列表
}
公共列表转换器(B型)
{
返回一些列表
}
}
为什么?如果你只是要沮丧,界面的意义是什么?您甚至不知道有哪些属性/方法可用。如果您进行了is/as转换,至少您知道类型。那么它是否不起作用?--但是为什么呢?之后你打算用它们做什么?所有这些类都是不同的,但从那里我可以得到我在一个特定对象中封装的公共属性。我在一个工厂类中进行了这种转换,该工厂类有一个ConvertTo方法,它对每个具体对象都是重载的。我将把它添加到帖子中。我想调用一个识别对象类型的工厂。我在帖子上添加了更多细节,请看。。。由于您已经定义了一个接口,我认为解决方案是将ConvertToMeasure移动到您的接口。公共类A:Iload{//something}公共类B:Iload{//something}我试图避免这个解决方案,因为每次我需要添加一个新类,比如类,我都需要使用OCP原则D@Devsined如果您的逻辑取决于类型(对于A返回XX,对于B返回YY),然后,唯一的解决方案是要么将类型知识嵌入到处理函数中,要么更改现有的类型以在本机上支持此功能。
List<ILoad> list = new List<ILoad>();
list = GetALlIloads();
Factory f = new Factory();
foreach (var item in list)
{
dynamic concreteType = item;
var converted = f.ConvertToMeasure(concreteType);
}
public class A: Iload
{
// something
}
public class B: ILoad
{
//Something
}
public class Factory
{
public List<Measure> ConvertToMeausre(A model)
{
return some List<Measure>
}
public List<Measure> ConvertToMeausre(B model)
{
return some List<Measure>
}
}