C# 为什么这个c构造函数不能按预期工作?

C# 为什么这个c构造函数不能按预期工作?,c#,constructor,C#,Constructor,如果使用符合特定条件的参数调用构造函数,并且我有以下代码,我将尝试以不同的方式初始化构造函数 class MessageEventArgs : EventArgs { private int _pId; private string _message; private string _channelPath; public MessageEventArgs(string message) { _pId = Process.GetCurre

如果使用符合特定条件的参数调用构造函数,并且我有以下代码,我将尝试以不同的方式初始化构造函数

class MessageEventArgs : EventArgs
{
    private int _pId;
    private string _message;
    private string _channelPath;

    public MessageEventArgs(string message)
    {
        _pId = Process.GetCurrentProcess().Id;
        _message = message;
        _channelPath = null;
    }

    public MessageEventArgs(string[] details)
    {
        if (details.Length == 1)
        {
            new MessageEventArgs(details[0]);
            return;
        }
        _pId = int.Parse(details[0]);
        _message = details[1];
        _channelPath = details[2];
    }
}

令人惊讶的是,在调试和逐行遍历时,我看到所有调用都正确,但在实例化之后,pId和_message有它们的默认值,即0和null,您不能从构造函数返回任何内容。试试这样的

    if (details.Length == 1)
    {
        _pId = Process.GetCurrentProcess().Id;
         _message = message;
        _channelPath = null;
    }
    else 
    {
        _pId = int.Parse(details[0]);
        _message = details[1];
        _channelPath = details[2];
    }

您不是在调用另一个构造函数,而是在创建第二个实例,并使用默认值初始化该实例

因此,第一个实例仍然未初始化

您需要这样做:

class MessageEventArgs : EventArgs
{
    private int _pId;
    private string _message;
    private string _channelPath;

    public MessageEventArgs(string message)
    {
        _pId = Process.GetCurrentProcess().Id;
        _message = message;
        _channelPath = null;
    }

    public MessageEventArgs(string[] details)
    {
        if (details.Length == 1)
        {
            _pId = Process.GetCurrentProcess().Id;
            _message = details[0];
            _channelPath = null;
            return;
        }
        _pId = int.Parse(details[0]);
        _message = details[1];
        _channelPath = details[2];
    }
}
class MessageEventArgs : EventArgs
{
    private int _pId;
    private string _message;
    private string _channelPath;

    public MessageEventArgs(string message)
    {
        _pId = Process.GetCurrentProcess().Id;
        _message = message;
        _channelPath = null;
    }

    public MessageEventArgs(string[] details)
    {
        if (details.Length == 1)
        {
            _pId = Process.GetCurrentProcess().Id;
            _message = details[0];
            _channelPath = null;
        }
        else 
        {
            _pId = int.Parse(details[0]);
            _message = details[1];
            _channelPath = details[2];
        }
    }
}

我可能还会检查详细信息是否为空。

根据规范,在C中,您不能从类调用另一个构造函数。所以这不是return语句,而是调用另一个构造函数的错误尝试。您必须创建一个Initialize方法,该方法体现了您要做的事情,并从两个方法中调用它

class MessageEventArgs : EventArgs
{
    private int _pId;
    private string _message;
    private string _channelPath;

    public MessageEventArgs(string message)
    {
        Initialize( message );
    }

    public MessageEventArgs(string[] details)
    {
        if (details.Length == 1)
        {
            Initialize( details[ 0 ] );
            return;
        }

        _pId = int.Parse(details[0]);
        _message = details[1];
        _channelPath = details[2];
    }

    private void Initialize(string message)
    {
        _pId = Process.GetCurrentProcess().Id;
        _message = message;
        _channelPath = null;     
    }
}

不确定这是否是清洁剂,但您可以尝试以下方法:

    public MessageEventArgs(string message)
        : this(new [] {message})
    {
    }

    public MessageEventArgs(string[] details)
    {
        if (details.Length == 1)
        {
            _pId = Process.GetCurrentProcess().Id;
            _message = details[0];
            _channelPath = null;
        }
        else
        {
            _pId = int.Parse(details[0]);
            _message = details[1];
            _channelPath = details[2];
        }
    }

不能从构造函数调用同一类的构造函数。您的代码创建了MessageEventArgs的本地实例,并且它超出了范围,这就是您没有看到预期行为的原因

构造函数用于根据传递的参数创建对象的实例。重载意味着允许传递不同的参数,并导致对象的正确实例化。构造函数是原子的,因此如果删除一个构造函数,它不会影响其他构造函数

您的代码应该如下所示:

class MessageEventArgs : EventArgs
{
    private int _pId;
    private string _message;
    private string _channelPath;

    public MessageEventArgs(string message)
    {
        _pId = Process.GetCurrentProcess().Id;
        _message = message;
        _channelPath = null;
    }

    public MessageEventArgs(string[] details)
    {
        if (details.Length == 1)
        {
            _pId = Process.GetCurrentProcess().Id;
            _message = details[0];
            _channelPath = null;
            return;
        }
        _pId = int.Parse(details[0]);
        _message = details[1];
        _channelPath = details[2];
    }
}
class MessageEventArgs : EventArgs
{
    private int _pId;
    private string _message;
    private string _channelPath;

    public MessageEventArgs(string message)
    {
        _pId = Process.GetCurrentProcess().Id;
        _message = message;
        _channelPath = null;
    }

    public MessageEventArgs(string[] details)
    {
        if (details.Length == 1)
        {
            _pId = Process.GetCurrentProcess().Id;
            _message = details[0];
            _channelPath = null;
        }
        else 
        {
            _pId = int.Parse(details[0]);
            _message = details[1];
            _channelPath = details[2];
        }
    }
}

显示实际创建MessageEventArgs实例的行。返回实际上是为了防止进一步执行。这就是为什么我想知道它是否是错的。我有点困惑,如果你的陈述是正确的@jgauffin的答案应该是错误的,因为他显然是从构造函数返回的。他不是想从构造函数返回什么。哦!非常感谢,我现在明白了。我会这样做,但为什么不:这个新的[]{Process.GetCurrentProcess.Id,message,null}并避免细节。完全检查长度?Process.GetCurrentProcess.Id是一个int,因此无法编译。我决定不将和int转换为字符串,然后再转换回int,因为它看起来有点凌乱。改为进行长度检查。这是有道理的,尽管我个人只会在.ToString上打一巴掌。首选项和非首选项。为什么不重载构造函数?这就是重载的作用。重载在这种情况下不起作用的原因是因为不能从类中显式调用另一个构造函数。他试图不让两个构造函数有重复的逻辑。我下面的例子只有一个构造函数有逻辑,另一个是空的。您只需使用:this…来重载ctor,但创建新阵列会增加额外的开销,并且您的解决方案不可扩展。考虑他是否有另一个构造了两个字符串的构造函数。然后是三根弦。等等…当然可以,但超载实际上是可能的