【问题标题】:c# using other class methodc# 使用其他类方法
【发布时间】:2016-11-22 14:20:10
【问题描述】:

感谢 NHMountainGoat 的解答! 实现接口看起来是一个不错的选择,所以我们只实例化了“需要”的方法。 现在看起来像这样: 编辑

class Machine
{
    //REM: MachineConnexion is a link to the main server where asking the data
    internal linkToPLC LinkToPLC;
    public IlinkToPLC ILinkPLC;
    public interface IlinkToPLC//Interface to linkPLC
    {
        Int16 MachineNumIS { get; set; }
    }
    internal class linkToPLC : IlinkToPLC
    {
        private Int16 Act_MachineNum;
        private List<string> genlnkPLCCanvas;
        private List<string> genlnkPLCworkingwith;
        static private List<string> ListSymbolNoExist;
        private string[] ListToPLClnk = {
                          "GlobalFolder.PMachine[{0}].",
                          "GlobalFolder.PMachine[{0}].STATE.",
                          "GlobalFolder.Machine[{0}].",
                          "GlobalFolder.Machine[{0}].STATE.",
                        };
        public linkToPLC()//ctor
        {
            genlnkPLCCanvas = new List<string>(ListToPLClnk);
            genlnkPLCworkingwith = new List<string>(ListToPLClnk);
            ListSymbolNoExist = new List<string>();
            Act_MachineNum = MachineNumIS;
        }
        public Int16 MachineNumIS { get { return (Int16)ReadWriteMachine("data"); } set { ReadWriteMachine("data", value); } }
        public string ValueExist(string ValueToreach, bool WorkingDATA = false)
        {
            if (!WorkingDATA)
            {
                for (int inc = 0; inc < genlnkPLCworkingwith.Count; inc++)
                {
                    string StrValueToReach = genlnkPLCworkingwith[inc] + ValueToreach;
                    if (MachineConnexion.SymbolExists(StrValueToReach))
                    {
                        ListSymbolNoExist.Clear();
                        return StrValueToReach;
                    }
                    else ListSymbolNoExist.Add(genlnkPLCworkingwith[inc] + ValueToreach);
                }
            }
            else if (WorkingDATA)
            {
                string StrValueToReach = genlnkPLCworkingwith[10] + ValueToreach;
                if (MachineConnexion.SymbolExists(StrValueToReach))
                {
                    ListSymbolNoExist.Clear();
                    return StrValueToReach;
                }
                else ListSymbolNoExist.Add(genlnkPLCworkingwith[10] + ValueToreach);
            }
            if (ListSymbolNoExist.Count != 0)
            {
                string ErrorList = "";
                for (int inc = 0; inc < ListSymbolNoExist.Count; inc++)
                {
                    ErrorList = string.Concat(ErrorList + "Num: " + inc.ToString() + " " + ListSymbolNoExist[inc].ToString() + "\n");
                }
                Console.WriteLine("Error" + ErrorList);
            }
            return null;
        }
        public object ReadWriteMachine(string VariableName, object DataToWrite = null, bool WorkingDATA = false)
        {
            string valueToFind = "";
            if (ValueExist(VariableName) != "FALSE")
            {
                if (DataToWrite != null) { MachineConnexion.WriteSymbol(valueToFind, DataToWrite); }
                return MachineConnexion.ReadSymbol(valueToFind);
            }
            return VariableName;
        }
    }
    public Machine()                  //constructor
    {
        LinkToPLC = new linkToPLC();
    }
}

并且告诉我引用对象没有定义到对象的实例.....在以下行中不起作用: Machine() LinkToPLC = new linkToPLC();//REM 我发现了这个错误,是我;o)) 24112016

//REM 24112016

这两个概念之间的主要区别是什么:静态实例和接口?

例子:

  class Program
{
    static void Main(string[] args)
    {
        ITestInterface InterInstance = new TestInterface();
        //test Interface
        bool value1 = true;
        value1 = InterInstance.invert(value1);
        InterInstance.print(value1);
        //test Instance static
        TestStaticInstance staticInstance = new TestStaticInstance();
        staticInstance.Instance.invert(value1);
        staticInstance.Instance.print(value1);
        Console.ReadKey();
    }
}
class TestInterface : ITestInterface
{
    public bool invert(bool value)
    {
        return !value;
    }
    public void print(bool value)
    { 
    Console.WriteLine(value.ToString()+"\n");
    }
    private void methodX()
    { }
}
interface ITestInterface
{
    bool invert(bool value);
    void print(bool value);
}
public class TestStaticInstance
{
    public TestStaticInstance Instance;
    public TestStaticInstance()
    {
        Instance = this;
    }
    internal bool invert(bool value)
    {
        return !value;
    }
    internal void print(bool value)
    {
        Console.WriteLine(value.ToString());
    }
}

谢谢

【问题讨论】:

  • 不要将继承视为代码重用的工具。有很多方法可以做到这一点 - 组合,实用程序类,静态方法等。继承意味着“is-a”关系 - 如果otherstuff is a linktoPLC 那么继承可能是合适的。如果它只是包含一个需要一个 PLC,那么组合可能是正确的选择。
  • 没有副本 - 每个linktoPLC 实例,包括needanotherone,都有自己的genlnkPLCworkingwith 集合。考虑一个带有List&lt;Flea&gt; fleas 集合的基类Animal - 每个Dog 和每个Cat 都有自己的跳蚤集合,而myDog.Scratch() 只能从他的集合中删除跳蚤。将其设为静态 导致该集合仅存在一次 - 但我不确切知道您要实现的目标。
  • 再次阅读您的问题我很困惑-您是在问needanotheroneLinkToPLC 是否共享genlnkPLCworkingwith 引用的列表?答案是否定的。由于您询问virtualoverride,我不确定您要做什么-virtualoverride 适用于方法,而不适用于数据 i>.
  • 请注意,这是合法的,您将通过 weach 变量引用相同的列表:linktoPLC LinkToPLC = new linktoPLC(); otherstuff needanotherone = LinktoPLC;
  • 如果您不想在副本中进行更改,而是想更改主变量(列表),只需将该变量设为静态,这样就不允许为任何实例创建新副本。

标签: c# inheritance static-methods


【解决方案1】:

你能构造你的其他类来获取链接类的实例吗?见:

/// <summary>
/// just a stub to demonstrate the model
/// </summary>
internal class Machine
{
    public string ReadData() { return "this is data"; }
    public void WriteData(string data) { Console.WriteLine(data); }
}

internal interface IMachineDataAccessor
{
    string Read();
    void Write(string data);
}

class LinkClass : IMachineDataAccessor
{
    protected Machine _machine;

    public LinkClass(Machine machine)
    {
        _machine = machine;
    }

    public void DoMyWork()
    {
        // insert work somewhere in here.

        string dataFromMachine = Read();

        Write("outbound data");
    }

    public string Read()
    {
        return _machine.ReadData();
    }

    public void Write(string data)
    {
        _machine.WriteData(data);
    }
}

class PersistentClass
{
    IMachineDataAccessor _machineImpl;

    public PersistentClass(IMachineDataAccessor machineAccessImplementation) 
    {
        _machineImpl = machineAccessImplementation;
    }

    public void DoMyWork()
    {
        string dataFromMachine = _machineImpl.Read();

        // insert work here.  Or anywhere, actually..

        _machineImpl.Write("outbound data");
    }
}

class StateClass
{
    IMachineDataAccessor _machineImpl;

    public StateClass(IMachineDataAccessor machineAccessImplementation) 
    {
        _machineImpl = machineAccessImplementation;
    }

    public void DoMyWork()
    {
        string dataFromMachine = _machineImpl.Read();

        // insert work here.  Or anywhere, actually..

        _machineImpl.Write("outbound data");
    }
}

static void Main(string[] args)
{
    LinkClass link = new LinkClass(new Machine());
    PersistentClass persistent = new PersistentClass(link as IMachineDataAccessor);
    StateClass state = new StateClass(link as IMachineDataAccessor);

    persistent.DoMyWork();
    state.DoMyWork();
    link.DoMyWork();
}

【讨论】:

  • Jablonovo,你能把我的回复标记为答案吗?我需要声望点。另外,我绝对希望您重组代码 - 但我看到您正在 Persistence 和 State 类中创建 LinkClass 的新实例 - 我认为将其保留为一个实例很重要 - 如果是这样,那么我会回到在构造函数中引用。这样,只能创建和共享一个实例。你清楚类和实例之间的区别吗?
  • 完成。我想我很清楚,一个类就像一个对象的画布,一个实例是从地板上升起的对象,它与一个灵魂、一个名字和一些它可以做或不能做的事情相提并论。由于 linkclass 是机器的一部分,我需要访问它,但不是全部,所以我保护了其余部分免于对其进行任何操作。这些接口实例是否只实现了我放在接口中的方法?或者它是实例化整个事情,但只允许访问引用的方法?感谢您的帮助。
  • 您的第二个问题是正确的 - 整个类被实例化,但只有接口(接口的方法)可供您的其他消费者使用。接口提供的好处远远超出此用途..顺便说一句。
猜你喜欢
  • 1970-01-01
  • 2016-10-05
  • 1970-01-01
  • 2013-05-07
  • 1970-01-01
  • 2010-12-12
  • 2021-05-29
  • 2014-10-10
  • 2012-04-03
相关资源
最近更新 更多