在C#和反射中从接口类型转换为具体类型

在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

Hi有几个实现一个接口的类。我想将ILoad列表中的项转换为its的具体类,就像这样。我想调用工厂转换器来获得另一个类型

 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>
    }
}