gtk#: 树视图对象总是作为引用调用传递
gtk#: Tree View object always passed as call-by-reference
似乎我在处理树视图的方法调用中的参数总是作为引用调用完成的。
我在顶层 window 上有一个可见的 GTK "Tree View" 控件。数据由各自模型写入。
现在我想删除一些列(基于用户设置的选项)并将操作的树视图传递给导出函数。
为了仅从输出中删除列,而不是从 GUI 本身中删除列,我想到将可见的树视图控件复制到一个临时控件中,操作临时控件并调用临时控件的导出功能.
我的问题是:即使我传递我的原点,可见树视图作为按值引用(据我所知),原点将被操纵并且列的删除将在可视树视图上完成.
似乎我在方法调用中的参数总是作为引用调用完成的。
代码:
"treeview1"是视觉Gtk.Tree视图...
我调用导出函数:
...
TreeView treeviewExport = SetExportViewAccordingToCheckboxes(treeview1);
ExportFile(treeviewExport);
...
在 SetExportViewAccordingToCheckboxes() 方法中,我只是将全局 treeview1 作为按值调用传递,在内部对其进行操作,然后 return 被操作的树视图:
protected static TreeView SetExportViewAccordingToCheckboxes(TreeView tvSource)
{
TreeView tvRet = tvSource;
if (cbName == false)
tvRet.RemoveColumn( ... );
...
return tvRet;
}
但是即使我已经从内部树视图 "tvRet" 中删除了列,我的视觉控件 "treeview1" 仍然缺少从 "tvRet" 中删除的所有列;看起来 "treeview1" 是作为引用调用传递的。
问题:这是为什么?
注意:我也尝试使用关键字 "in" 没有任何区别:
protected static TreeView SetExportViewAccordingToCheckboxes(in TreeView p_tvSource)
问题来了:
In the method SetExportViewAccordingToCheckboxes() I just pass the
global treeview1 as call-by-value, manipulate it internally and return
the manipulated Tree View:
protected static TreeView SetExportViewAccordingToCheckboxes(TreeView tvSource)
{
TreeView tvRet = tvSource;
if (cbName == false)
tvRet.RemoveColumn( ... );
...
return tvRet;
}
首先介绍一下背景。在 C# 术语中,value types are those that directly contain a value, while reference types 是引用数据的那些,而不是直接持有它。
因此,int x = 5
表示您正在创建整数类型的值对象5,并将其存储在x
中,而TreeView tree = new TreeView()
表示您正在创建一个引用tree
类型 TreeView,指向相同类型的对象。
所有这些意味着您不能按值传递对象,即使您愿意。在最好的情况下,您按值传递引用,这没有任何效果。
所以,下一步就是复制数据,修改复制的对象而不是原来的对象。这在理论上是合理的,但行:TreeView tvRet = tvSource;
不幸的是没有实现。是的,您正在创建一个新引用,但是该引用指向与原始引用指向的对象相同的对象。
现在,假设我们正在管理 class Point 而不是 TreeView 的对象,其属性为 x 和 y.
class Point {
public int X { get; set; }
public int Y { get; set; }
}
您可以轻松创建一个点:
Point p1 = new Point { X = 5, Y = 7 };
但这并没有复制它:
Point p2 = p1;
这样做:
Point p2 = new Point { X = p1.X, Y = p1.Y };
现在最初的问题是您想将一些列传递给 Export() 函数。在这种情况下,您只需要将过滤列的向量传递给导出函数,而不是 TreeView.
的副本
void PrepareExporting()
{
var columns = new List<TreeViewColumn>();
foreach(TreeViewColumn col in this.treeView.Columns) {
if ( this.Filter( col ) ) {
columns.add( col );
}
}
this.Export( columns.ToArray() );
}
void Export(TreeViewColumn[] columns)
{
// ...
}
我认为这会更容易,因为不需要尝试实现按引用传递(不可能),也不需要复制树视图。
希望这对您有所帮助。
似乎我在处理树视图的方法调用中的参数总是作为引用调用完成的。
我在顶层 window 上有一个可见的 GTK "Tree View" 控件。数据由各自模型写入。
现在我想删除一些列(基于用户设置的选项)并将操作的树视图传递给导出函数。
为了仅从输出中删除列,而不是从 GUI 本身中删除列,我想到将可见的树视图控件复制到一个临时控件中,操作临时控件并调用临时控件的导出功能.
我的问题是:即使我传递我的原点,可见树视图作为按值引用(据我所知),原点将被操纵并且列的删除将在可视树视图上完成.
似乎我在方法调用中的参数总是作为引用调用完成的。
代码:
"treeview1"是视觉Gtk.Tree视图...
我调用导出函数:
...
TreeView treeviewExport = SetExportViewAccordingToCheckboxes(treeview1);
ExportFile(treeviewExport);
...
在 SetExportViewAccordingToCheckboxes() 方法中,我只是将全局 treeview1 作为按值调用传递,在内部对其进行操作,然后 return 被操作的树视图:
protected static TreeView SetExportViewAccordingToCheckboxes(TreeView tvSource)
{
TreeView tvRet = tvSource;
if (cbName == false)
tvRet.RemoveColumn( ... );
...
return tvRet;
}
但是即使我已经从内部树视图 "tvRet" 中删除了列,我的视觉控件 "treeview1" 仍然缺少从 "tvRet" 中删除的所有列;看起来 "treeview1" 是作为引用调用传递的。
问题:这是为什么?
注意:我也尝试使用关键字 "in" 没有任何区别:
protected static TreeView SetExportViewAccordingToCheckboxes(in TreeView p_tvSource)
问题来了:
In the method SetExportViewAccordingToCheckboxes() I just pass the global treeview1 as call-by-value, manipulate it internally and return the manipulated Tree View:
protected static TreeView SetExportViewAccordingToCheckboxes(TreeView tvSource) { TreeView tvRet = tvSource; if (cbName == false) tvRet.RemoveColumn( ... ); ... return tvRet; }
首先介绍一下背景。在 C# 术语中,value types are those that directly contain a value, while reference types 是引用数据的那些,而不是直接持有它。
因此,int x = 5
表示您正在创建整数类型的值对象5,并将其存储在x
中,而TreeView tree = new TreeView()
表示您正在创建一个引用tree
类型 TreeView,指向相同类型的对象。
所有这些意味着您不能按值传递对象,即使您愿意。在最好的情况下,您按值传递引用,这没有任何效果。
所以,下一步就是复制数据,修改复制的对象而不是原来的对象。这在理论上是合理的,但行:TreeView tvRet = tvSource;
不幸的是没有实现。是的,您正在创建一个新引用,但是该引用指向与原始引用指向的对象相同的对象。
现在,假设我们正在管理 class Point 而不是 TreeView 的对象,其属性为 x 和 y.
class Point {
public int X { get; set; }
public int Y { get; set; }
}
您可以轻松创建一个点:
Point p1 = new Point { X = 5, Y = 7 };
但这并没有复制它:
Point p2 = p1;
这样做:
Point p2 = new Point { X = p1.X, Y = p1.Y };
现在最初的问题是您想将一些列传递给 Export() 函数。在这种情况下,您只需要将过滤列的向量传递给导出函数,而不是 TreeView.
的副本void PrepareExporting()
{
var columns = new List<TreeViewColumn>();
foreach(TreeViewColumn col in this.treeView.Columns) {
if ( this.Filter( col ) ) {
columns.add( col );
}
}
this.Export( columns.ToArray() );
}
void Export(TreeViewColumn[] columns)
{
// ...
}
我认为这会更容易,因为不需要尝试实现按引用传递(不可能),也不需要复制树视图。
希望这对您有所帮助。