从C#中的另一个类获取一个类的公共变量的值

时间:2018-10-30 14:05:59

标签: c#

首先对问题/标题表示歉意。我找不到合适的标题。任何建议都非常欢迎。

我有一个C#应用程序,其逻辑类似于以下内容:

public ClassA {
    public string myID { get; set; }

    public void SetID(string jobID)
    {
        myID = jobID;    
    }

    public void SomeMethod(){
        ClassB b = new ClassB();
        LogMessage("Execution starts here");
        b.FetchData();
        LogMessage("Further execution");

    }
    public void LogMessage (string message){

        //some logic to write message into a text file with the following message :

        // "Id : " + myID + " --> " + message
    // next line (enter)
    }
}

public class ClassB(){

    public void FetchData(){
        ClassA a = new ClassA();
        a.LogMessage("Fetch data starts");
        //some logic to fetch data
        a.LogMessage("Fetch data ends");
    }

}

如果id值说为“ ABC”,则执行后的文本文件如下所示:

Id : ABC --> Execution starts here
Id : (null) --> Fetch data starts
Id : (null) --> Fetch data ends
Id : ABC --> Further execution

我面临的问题是即使id是一个公共变量,id也不会被打印。当执行进入另一个类时,myId变量变为null。出于某些原因,我也无法传递{{ 1}}变量作为myId的参数。

谁能告诉我总是简单的方法来获取myId值,而不会在所有方法中都将其设置为null。上面的代码只是我在应用程序中拥有的示例,这种相似的日志记录在很多方法中都可以完成。因此,如果有人可以提出可以在LogMessage()中进行更改的建议,那么这对我会有很大帮助。

请让我知道是否需要任何进一步的说明来理解该问题。

4 个答案:

答案 0 :(得分:2)

LE:我看到您纠正了变量错字,现在我看到了问题。

在ClassB内部,您再次实例化包含LogMessage的ClassA,但是您没有调用SetID(因此myID为null)。

LE2:在这些类的任何一个中,我都不会使用log方法,因为SOLID原则中的S声明(一个类需要承担单个责任)。您可以采用的一种方法是创建一个处理日志逻辑的静态类:

public static class Logger
{
    private static string myID;

    public static SetMyId(string id)
    {
        myID = id;
    }

    public static void Log(string message)
    {
        //print myID _+ message
    }
}

只要应用程序处于活动状态,静态变量就会保留您的ID。当然,确实有一些模式可用于此目的,因此根据您的上下文,根据您的需求(我在一个简单的Google搜索中发现的example)探索其他不同的选项以及执行该操作的库可能会很不错。为您记录日志(某些示例here

答案 1 :(得分:1)

每个类实例都存在类变量,也称为字段(在这里我不是在谈论静态字段)。也就是说,每个对象都有自己的一组字段值。

ClassB中,用ClassA a = new ClassA();创建一个新对象。这与您呼叫SomeMethod的对象不同。

您可以通过构造函数注入将ClassA对象传递给ClassB。将ClassB更改为

public class ClassB()
{
    private readonly ClassA _a;

    // Constructor. You call it with `new ClassB(classAObject)`.
    public ClassB(ClassA a)
    {
        _a = a;
    }

    public void FetchData(){
        _a.LogMessage("Fetch data starts");
        // Fetching data here...
        _a.LogMessage("Fetch data ends");
    }
}

ClassA中将SomeMethod更改为

public void SomeMethod()
{
    myID = "ABC";

    // Pass a reference to the current object (this).
    ClassB b = new ClassB(this);

    LogMessage("Execution starts here");
    b.FetchData();
    LogMessage("Further execution");
}

此外,由于SetID属性已经具有公共设置器,因此没有必要创建方法myID

答案 2 :(得分:0)

您需要在日志消息中添加字符串,因为您要传递一个名为message的变量,该变量应该是字符串?

class QPushButton(QAbstractButton):
    """
    QPushButton(parent: QWidget = None)
    QPushButton(str, parent: QWidget = None)
    QPushButton(QIcon, str, parent: QWidget = None)
    """
    def actionEvent(self, *args, **kwargs): # real signature unknown
        pass

    def autoDefault(self): # real signature unknown; restored from __doc__
        """ autoDefault(self) -> bool """
        return False

    def changeEvent(self, *args, **kwargs): # real signature unknown
        pass

在B类中,没有指向您创建的A类实例的引用指针。因此,我不确定您如何调用该方法。

添加

public void LogMessage (string message){

        //some logic to write message into a text file with the following message :

        // "Id : " + myID + " --> " + message
    // next line (enter)
    }

答案 3 :(得分:0)

只需简单介绍一下如何解耦:“快速且非常脏”:

public class Logger {
    public void LogMessage (string message, string myID){

        //some logic to write message into a text file with the following message :

        // "Id : " + myID + " --> " + message
    // next line (enter)
    }
}

public ClassA {
    private Logger logger = new Logger();

    public string myID { get; set; }

    // SetID is actually not necessary: just use classAInstance.myID = jobID; in the client of ClassA.
    // But I'd recommend making the Property Readonly and set it through CTOR if possible.


    public void SomeMethod(){
        ClassB b = new ClassB();
        logger.LogMessage("Execution starts here", myID);
        b.FetchData(logger, myID);
        logger.LogMessage("Further execution", myID);

    }

}

public class ClassB(){

    public void FetchData( Logger logger, string myID){

        logger.LogMessage("Fetch data starts", myID);
        //some logic to fetch data
        logger.LogMessage("Fetch data ends", myID);
    }
}

可以通过以下方法进一步改进:

  • 使用Logger接口
  • 使用日志记录框架
  • 使用依赖注入
  • 使用接口和DI将ClassB与ClassA分离。
  • ...