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 的对象,其属性为 xy.

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)
{
    // ...
}

我认为这会更容易,因为不需要尝试实现按引用传递(不可能),也不需要复制树视图。

希望这对您有所帮助。