托管类型的C#指针

本文关键字:指针 类型 | 更新日期: 2023-09-27 18:19:38

根据方法中的参数,我希望更改类中的不同变量并对其执行操作。在C++中,这非常容易,但在C#中,如果没有大量的if/else语句,这似乎更难。在C#中有更好的方法吗?

在C++中,它看起来像(我用C++编码已经有几年了,所以要善良):

void MyMethod(int option)
{
    int* _i;
    string* _s;
    MyClass* _mc; // My created class
    DataGridViewColumn _col; // Managed class
    if(option == 0)
    {
        _i = &m_SomeInt;
        _s = &m_SomeStr;
        _mc = &m_SomeMC;
        _col = &m_SomeCol;
    }
    else if(option == 1)
    {
        _i = &m_SomeOtherInt;
        _s = &m_SomeOtherStr;
        _mc = &m_SomeOtherMC;
        _col = &m_SomeOtherCol;
    }
    // Now I can act on _i, _s, etc and Im really acting on the member variables.
    _i = 5;
    _s = "Changed String";
    .....
}

这是我想做的,但在C#中。但这是我的解决方案,最后很混乱:

void MyMethod(int option)
{
    int _i;
    string _s;
    MyClass _mc; // My created class
    DataGridViewColumn _col; // Managed class
    if(option == 0)
    {
        _i = m_SomeInt;
        _s = m_SomeStr;
        _mc = m_SomeMC;
        _col = m_SomeCol;
    }
    else if(option == 1)
    {
        _i = m_SomeOtherInt;
        _s = m_SomeOtherStr;
        _mc = m_SomeOtherMC;
        _col = m_SomeOtherCol;
    }
    _i = 5;
    _s = "Changed String";
    .....
    if(option == 0)
    {
        m_SomeInt = _i;
        m_SomeStr = _s;
        m_SomeMC = _mc;
        m_SomeCol = _col;
    }
    else if(option == 1)
    {
        m_SomeOtherInt = _i;
        m_SomeOtherStr = _s;
        m_SomeOtherMC = _mc;
        m_SomeOtherCol = _col;
    }
}

托管类型的C#指针

在C#中,您需要将它们封装在一个容器中,然后在两个容器之间进行选择

class DataContainer
{
    public int I {get; set;}
    public string S {get;set;}
    public MyClass Mc {get;set;}
    public DataGridViewColumn Col {get;set;}
}
void MyMethod(int option)
{
    DataContainer container;    
    if(option == 0)
    {
        container = m_SomeContainer;
    }
    else if(option == 1)
    {
        container = m_SomeOtherContainer;
    }
    else
    {
         throw new ArgumentOutOfRangeException(nameof(option));
    }
    container.I = 5;
    container.S = "Changed String";
    .....
}

一个更好的选择是不接受一个选项,而是传入容器类本身。

void MyMethod(DataContainer container)
{
    container.I = 5;
    container.S = "Changed String";
    .....
}

似乎可以颠倒逻辑以减少代码重复:

void MyMethod(int option)
{
    int i = 5;
    string s = "Changed String";
    MyClass* _mc = /* not sure what goes here */
    DataGridViewColumn _col = /* not sure what goes here */
    if(option == 0)
    {
        m_SomeInt = i;
        m_SomeStr = s;
        m_SomeMC = mc;
        m_SomeCol = col;
    }
    else if(option == 1)
    {
        m_SomeOtherInt = i;
        m_SomeOtherStr = s;
        m_SomeOtherMC = mc;
        m_SomeOtherCol = col;
    }
}

或者,您可以创建一个包含要更改的值的类,并使用对的引用。然后你不需要有两个不同的变量集——你有两个不一样的变量,每个变量引用一个封装这些值的类。

谢谢。我已经使用了你所有的答案,并创建了以下内容(为了保护无辜者,已经更改了名称):

class DataContainer
{
    public int I {get; set;}
    public string S {get;set;}
    public MyClass Mc {get;set;}
    public DataGridViewColumn Col {get;set;}
}
void MyMethod(int option)
{
    DataContainer container;    
    if(option == 0)
    {
        Helper(new DataContainer(m_SomeInt, ...));
    }
    else if(option == 1)
    {
        Helper(new DataContainer(m_SomeOtherInt, ...));
    }
    else
    {
         throw new ArgumentOutOfRangeException(nameof(option));
    }
}
void Helper(DataContainer container)
{
        container.I = 5;
        container.S = "Changed String";
        .....
}