我对编码很新,并且总是使用“classname instancename = new classname()”来创建实例,但是今天我发现以下代码没有遵循,也不适用于这种语法。我的问题是第5行发生了什么。非常感谢你。
private void _InsertIntoBinarySearchTree(ref Element<K> p , K key)
{
if (p == null)
{
p = new Element<K>();//what happens here?
p.key = key;
}
else
{
if (p.key.CompareTo(key) > 0)
{
_InsertIntoBinarySearchTree(ref p.left, key);
}
else if (p.key.CompareTo(key) < 0)
{
_InsertIntoBinarySearchTree(ref p.right, key);
}
else
{
throw new Exception("");
}
}
}
答案 0 :(得分:2)
p
如果在方法中ref
,那么无论你做什么,它都会受到影响;意味着当您使用new
分配时,方法参数p
的调用者也会被重新分配。
您在参数中声明它是Element<K>
类型,因此p
必须符合该类型。
在相关的方法中,您通过
将p
重新分配给new Element<K>
p = new Element<K>();//what happens here?
这与您p = new Element()
的使用情况相同,但由于Element
类型需要通用类型引用(可能是K
或其他任何内容)您还需要使用传递给方法的相同类型K
重新分配它。因为在调用时我们不确定K
是什么类型。
您未使用var p =...
或Element<K> p =..
的原因是因为p
已在参数中声明为该类型。这是ref
参数,因此您可以按照提及的方式重新分配。
该方法的调用者可能仅作为示例:
Element<string> p = null;
string k = "someKey";
_InsertIntoBinarySearchTree(ref p, k); //Here p goes into the method as ref; the method performs the null check and sets p as new Element<string>()
希望这会有所帮助......
答案 1 :(得分:1)
首先,您不能为变量p
使用类型说明符,因为您未声明新变量p
,而是分配< / em>现有变量的值。另见:
int myVal;
myVal = 5;
其次,您正在分配变量p
。因此,它将使用新值覆盖之前的任何内容 - 在本例中为new Element<K>()
。从技术上讲,这可能是任何值,但是因为你调用new
,它会创建一个新变量并调用相应的构造函数。不要担心内存泄漏 - C#将跟踪孤立的引用并为您清理它们。
最后,由于p
作为ref
传递给您的方法,因此分配给它将编辑方法的本地范围中的变量p
和传递给您的引用来自调用范围的方法,因此为什么分配给p
在这里作为输出很有用。
答案 2 :(得分:0)
您会注意到第一行的方法签名中的p变量的类是Element<K>
。忽略它通过ref传递的时刻,它类似于以下代码。
Element<K> p = new Element<K>();
Element是K类型的泛型类.K是要排序的对象的类型。它是通用的,因为您可以选择正在排序的元素的类型。例如,如果您要对汽车进行分类。
Element<Car> c = new Element<Car>();
允许哪些类型的逻辑在泛型Element<K>
类的定义中定义。