【问题标题】:c#: Calling common method of stored references to class objects from object[] arrayc#:从object []数组调用类对象的存储引用的常用方法
【发布时间】:2013-07-20 22:51:21
【问题描述】:

在对象类型上使用开关真的是调用对类对象的存储引用的通用函数的主要方式吗?它不必是“对象”值类型。

using System;

public class MainClass { public void Main() { print "hello world"; } }
public class SubClassOne : MainClass { }
public class SubClassTwo : MainClass { }

public class Storer
{
     public void Main() {
         object[] objects = new object[2];
         objects[0] = new SubClassOne();
         objects[1] = new SubClassTwo();
         for(i=0;i<2;i++)
         {
             switch(objects[i].GetType().ToString())
             {
                 case: "SubClassOne":
                     SubClassOne subclass = objects[i];
                     subclass.Main();
                     break;
                 case: "SubClassTwo":
                     SubClassTwo subclass = objects[i];
                     subclass.Main(); //Could probably call after the switch
                     break;
             }
         }
     }
}

注意:代码未解析,因此可能存在严重错误。

【问题讨论】:

  • 为什么不使用MainClass[] objects = new MainClass[2]
  • 当它真正存储 MainClass 时,我可以向它添加子类吗?没试过。
  • SubClassTwo 扩展了MainClass,因此您可以将其用作MainClass 而无需强制转换。使用objects[0].Main() 有效
  • 如果我的问题是正确的,为什么不试试这个 - objects[i].Main() 你能解释一下为什么你需要一个开关吗?
  • "Using objects[0].Main() is valid" 嗯...我记得builder说值类型'object'没有这样的方法,所以我添加了强制转换。

标签: c# class methods


【解决方案1】:

Stringly”类型的面向对象代码就是这样一个bad idea。你(几乎)永远不需要通过字符串知道对象的类型。

将您的“打印”更改为 Console.WriteLine 和 main 可以正常工作

    MainClass[] stuff = new MainClass[2];
    stuff[0] = new SubClassOne();
    stuff[1] = new SubClassTwo();
    foreach(var item in stuff)
    {
        item.Main();
    }

如果问题是您确定使用object 的数组,AlexH 已经回答了。

【讨论】:

    【解决方案2】:

    在这种情况下,我建议使用as keyword 来执行安全的强制转换操作:

    using System;
    
    public class MainClass { public void Main() { print "hello world"; } }
    public class SubClassOne : MainClass { }
    public class SubClassTwo : MainClass { }
    
    public class Storer
    {
        public void Main() {
         object[] objects = new object[2];
         objects[0] = new SubClassOne();
         objects[1] = new SubClassTwo();
         for(i=0;i<2;i++)
         {
            var myMainClass = objects[i] as MainClass;
            if (myMainClass != null)
            {
                myMainClass.Main();
            }
         }
     }
    }
    

    正如 wudzik 所说,将对象声明为 MainClass 数组应该会更好

    【讨论】:

    • 你说得对,你可以直接执行 as 操作,检查结果是否为空,谢谢
    【解决方案3】:

    有很多方法可以很好地解决这个问题,取决于:

    如果您知道类型并且类型不多:

    使用 LINQ OfType&lt;&gt;()。更多详情见MSDN

    foreach (var item in objects.OfType<SubClassOne>())
    {
       item.Main();
    }
    
    foreach (var item in objects.OfType<SubClassTwo>())
    {
       item.Main();
    }
    

    如果种类多,只介绍通用接口

    interface ISharedApi
    {
        void Main();
    }
    
    class SubClassOne : ISharedApi
    class SubClassTwo : ISharedApi
    

    并通过它实现/标记每个类型,然后你只需要一个循环:

    var objects = new List<ISharedApi>();
    objects.Add(new SubClassOne());
    objects.Add(new SubClassTwo());
    
    foreach (var item in objects)
    {
       item.Main();
    }
    

    【讨论】:

      【解决方案4】:

      您应该实现一个更加面向对象的解决方案。而不是创建一个由对象组成的数组,您应该使 MainClass 抽象并定义一个抽象方法 Main。之后,您应该在子类中实现 Main。

      通过这种方式,您可以将代码交换到:

      using System;
      
      public abstract class MainClass { public abstract void Main(); }
      
      public class SubClassOne : MainClass { 
          public override void Main() { print "SubClassOne, hello world"; } 
      }
      public class SubClassTwo : MainClass { 
          public override void Main() { print "SubClassTwo, hello world"; }
      }
      
      public class Storer
      {
          public void Main() {
              MainClass[] objects = new MainClass[2];
              objects[0] = new SubClassOne();
              objects[1] = new SubClassTwo();
      
              foreach(MainClass mc in objects)
              {
                  mc.Main();
              }
          }
      }  
      

      【讨论】:

        猜你喜欢
        • 2015-04-28
        • 2020-02-26
        • 2016-05-25
        • 1970-01-01
        • 1970-01-01
        • 2015-10-11
        • 2021-05-26
        • 2017-05-13
        • 1970-01-01
        相关资源
        最近更新 更多