C#指向托管类型的指针

时间:2015-10-27 15:12:05

标签: c# .net managed

根据我方法中的参数,我想在我的班级中更改不同的变量并对其进行操作。在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;
    }
}

3 个答案:

答案 0 :(得分:3)

在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";
    .....

}

答案 1 :(得分:1)

似乎你可以反转逻辑来减少代码重复:

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;
    }

}

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

答案 2 :(得分:0)

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

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";
        .....
}