指针是不安全的,但我不明白参考

时间:2016-12-09 19:33:57

标签: c# pointers ref

我想要一个" square"的单例问题2×2。 我希望能够逐行引用。 我希望能够逐个引用。 我知道我可以用指针轻松地在C ++中做到这一点,但这似乎是一个坏习惯。 我不明白如何链接我的" row"和我的"案例"一起。 列中也有相同的逻辑,但在代码中没有描述 目标是如此改变Case的值会影响Row中引用的值。如何在没有指针和Ref?

的情况下实现这一点
class Program
{
    static void Main(string[] args)
    {
        Problem.Instance().Show();
        Problem.Instance().Change();
        Problem.Instance().Show();
    }

    public class Problem
    {
        private Case[] cases = null;
        private Row[] rows = null;
        // same logic with private Column[] columns = null;

        static Problem instance = null;
        private Problem()
        {
            cases = new Case[4];
            rows = new Row[2];

            int i = 0;
            for (i = 0; i < 4; i++)
                cases[i] = new Case();

            for (i = 0; i < 2; i++)
                rows[i] = new Row(i);

        }
        public static Problem Instance()
        {
            if (instance == null)
                instance = new Problem();
            return instance;
        }
        public Case LinkToRow(int i, ref Row r)
        {
            cases[i].LinkToRow(r);
            return cases[i];
        }
        public void Show()
        {
            rows[0].Show();
        }
        public void Change()
        {
            cases[0].Change();
            cases[1].Change();
        }
    }
    public class Row
    {
        private Case[] ref cases = null;
        public Row(int i)
        {
            ref Row r = this;
            cases = new Case[2];
            cases[0] = Problem.Instance().LinkToRow(0, ref r);
            cases[1] = Problem.Instance().LinkToRow(1, ref r);
        }
        public void Show()
        {
            Console.WriteLine("{0},{1}", cases[0].Val, cases[1].Val);
        }
    }
    public class Case
    {
        private int val;
        private ref Row r = null;

        public Case()
        {
        }
        public void LinkToRow(Row rr)
        {
            r = rr;
        }
        public int Val { get { return val; } }
        public void Change()
        {
            val++;
        }
    }
}

2 个答案:

答案 0 :(得分:4)

在C#中,private Row r = null;声明了对Row实例的可重新引用的引用。 ref在那里是非法的,不需要。

在C ++中,private: Row r;将是Row的实例,而不是引用。 C ++是一种具有非常不同规则的不同语言。 C#类不能“堆叠”;它们总是动态分配,唯一可以操作的方法是通过引用。

在C#中,您的private Row r;已经是参考。 C#引用有点像指针,您不必(也不能)显式取消引用。因为它总是被解引用,所以你也不能做指针运算。他们受到许多相同的礼貌小说(“让他们假装它不是指针”)的C ++参考。只需取出ref即可。

C# struct (e.g. System.DateTime)更像是C ++类的堆栈实例。这与C ++结构/类的区别非常不同。

C# ref keyword是一种不同的动物。与参考文献无关。

在C#中,下面的示例说明了the ref keyword的用途:通过引用而不是按值传递引用。听起来我在拉你的腿,但我不是。

要根据C ++语义进行解释,通过“按值”传递C#引用就像传递指针一样。您可以更改调用者指针指向的对象,但不能更改调用者的指针本身。您只有调用者指针的

通过引用传递C#引用就像传入指针指针一样:你可以设置(*p)->Foo = 3;,你也可以设置*p = new Bar();(我生锈了关于C / C ++,欢迎更正)。

public static void F()
{
    String x = "original value";
    FByValue(x);
    Console.WriteLine(x);
    FByReference(ref x);
    Console.WriteLine(x);
}

public static void FByValue(String s)
{
    s = "different value for local copy of parameter only";
}

public static void FByReference(ref String s)
{
    s = "different value for caller's copy, thanks to ref keyword";
}

ref仅适用于参数,永远不会使用字段; see MSDN for more detail

最后:FByValue()FByReference()int代替String具有相同的语义。

答案 1 :(得分:0)

在C#中,值类型引用之间存在差异。

首先,C / C ++中的指针,语言的工作原理以及硬件的工作方式都没有错。它们可能会让新用户感到困惑。

在C#中,结构和类的定义与C ++不同:

如果您将数据结构定义为 struct class struct 是一个在调用调用时传递的对象。另一方面,获取其指针传递,类似于C ++指针,因此如果您在C#中引用了类实例,那么您实际上引用了同一个对象,并且完成了更改在一个地方会反映出你对该物体的引用。