C# 如何在DataTable行中存储multple columns对象

C# 如何在DataTable行中存储multple columns对象,c#,.net,datatable,reference,C#,.net,Datatable,Reference,如何在DataTable行中存储对象,并将其扩展为几列,或者在一列中存储对象,在另一列中引用此对象的属性 class MyDataTable : DataTable { public MyDataTable { this.Columns.Add("col1"); this.Columns.Add("col2") this.Columns.Add("Cat", typeof(Cat)) this.Col

如何在DataTable行中存储对象,并将其扩展为几列,或者在一列中存储对象,在另一列中引用此对象的属性

class MyDataTable : DataTable
{
    public MyDataTable
    {
        this.Columns.Add("col1");
        this.Columns.Add("col2")        
        this.Columns.Add("Cat", typeof(Cat))
        this.Columns.Add("CatType")

        Cat cat1 = new Cat("name1", "type1")
        Cat cat2 = new Cat("name2", "type2")
        this.Rows.add(new object[] {"value","value",cat1,cat1.type} )
        this.Rows.add(new object[] {"value","value",cat2,cat2.type} )

        // I want to show table like: 
        // |value|value|name1|type1|
        // |value|value|name2|type2|

        // while type should be a reference not a static string, so
        cat1.type = "type3"; //should be able to change table like:

        // |value|value|name1|type3|
        // |value|value|name2|type2|    
    }
} 

class Cat
{
    string name;
    string type;
    public Cat(...){..}

    public override string toString()
        return name;
}
或者像是在桌子上摆桌子

class MyDataTable : DataTable
{
    public MyDataTable
    {
        this.Columns.Add("col1");
        this.Columns.Add("col2")        
        this.Columns.Add("Cat", typeof(Cat))

        Cat cat1 = new Cat("name1", "type1")
        Cat cat2 = new Cat("name2", "type2")
        this.Rows.add(new object[] {"value","value",cat1} )
        this.Rows.add(new object[] {"value","value",cat2} )

        // And show table like: 
        // |value|value||name1|type1||
        // |value|value||name2|type2||
    }
} 

 class Cat : DataTable {
      public Cat(string name, string type){
        this.Columns.Add("name");
        this.Columns.Add("type");
        this.Rows.Add(name,type);
      } 
 }
但能够在以下位置显示Cat列:

 datagridview1.DataSource = new MyDataTable();
////

@雷内回答

当我将“type”设置为LiveString时:

datagridview.datasource = new List<Cat>(...)

DataTable的真正目的是在向其添加行时存储状态。您的用例似乎超出了它的设计能力

如果允许我们将
type
属性的不可变类型字符串替换为允许更改其值的类型,则用于添加对象的技巧也可用于类型。我们使用的事实是,对于对象类型的DataColumns,行将调用该对象上的
ToString

我将介绍一种名为
LiveString

class LiveString 
{
    string value;

    internal string Value {
        get{return value;}
        set{this.value= value;}
    }

    public LiveString(string value) {
       this.value = value;
    }

    // use an implicit operator
    public static implicit operator LiveString(string value)
    {
        return new LiveString(value);
    }

    public override string ToString() {
        return value;
    }
}
它的目标是包装一个字符串,并具有从字符串创建新对象的方法,但也获取和更改其内部状态。我使用了一个类,这样当前的
Cat
类的用户就不必对他们的代码进行太多的更改

您必须对代码进行如下调整:

class MyDataTable : DataTable
{
    public MyDataTable()
    {
        this.Columns.Add("col1");
        this.Columns.Add("col2");        
        this.Columns.Add("Cat", typeof(Cat));
        // notice the typeof here
        this.Columns.Add("CatType", typeof(LiveString));

        Cat cat1 = new Cat("name1", "type1");
        Cat cat2 = new Cat("name2", "type2");
        this.Rows.Add(new object[] {"value","value",cat1,cat1.type} );
        this.Rows.Add(new object[] {"value","value",cat2,cat2.type} );

        cat1.type = "type3"; 
    }
} 
还有你的猫课。注意,在类型setter上,我没有替换
\u type
上的当前对象,而是只替换它的
值。这保证了该行所持有的实例得到更新,而不是替换为该行中未存储或更新的新实例

class Cat
{
    string name;
    LiveString _type;
    public LiveString type {
        get 
        { 
            return _type;
        }
        set 
        {
            _type.Value = value.Value;
        }
    }

    public Cat(string name, string type){this.name= name; this._type = type;}

    public override string ToString()
    {
        return name;
    }
}

本例尝试尽可能接近数据表的使用。相反,您可以构建自己的集合,并为其提供元数据,这些元数据包括它所包含的类型以及您希望如何表示它们。我认为这在实现方面是有用的。其他选项可能是使用。

我认为不可能完全按照您的要求执行。请不要编辑我的答案。如果您有一个新问题,请随意回答,或者如果您在当前问题的上下文中有额外的信息,请单击。这将起作用。您似乎正在寻找可用于数据绑定的类型化集合。在那种情况下有很多可能性。DataTable是泛型、linq、动态和匿名类型出现之前的.NET1.0概念。
class Cat
{
    string name;
    LiveString _type;
    public LiveString type {
        get 
        { 
            return _type;
        }
        set 
        {
            _type.Value = value.Value;
        }
    }

    public Cat(string name, string type){this.name= name; this._type = type;}

    public override string ToString()
    {
        return name;
    }
}