C# 演员名单<;A>;列出<;B>;不做新的拷贝

C# 演员名单<;A>;列出<;B>;不做新的拷贝,c#,casting,C#,Casting,请遵守以下准则: public class MyClass { List<object> _List = new List<object>(); public List<object> Objects { get { return _List; } } public List<string> Strings { get { return _List.Cast<string>().ToList(); } }

请遵守以下准则:

public class MyClass
{
    List<object> _List = new List<object>();

    public List<object> Objects { get { return _List; } }
    public List<string> Strings { get { return _List.Cast<string>().ToList(); } }

    public void Test()
    {
        Objects.Add ("Hello");
        // actual contents
        // Objects = object[] { "Hello" }
        // Strings = string[] { "Hello" }

        Strings.Add ("World");
        // actual contents
        // Objects = object[] { "Hello" }
        // Strings = string[] { "Hello" }

        // expected contents
        // Objects = object[] { "Hello", "World" }
        // Strings = string[] { "Hello", "World" }
    }
}
public abstract class Foo
{
    List<object> _List = new List<object>();
    public List<object> ListObject { get { return _List; } }
}
public class Bar : Foo
{
    public List<string> ListString
    {
        get { return ListObject.Cast<string>().ToList(); }
    }
}

Bar oBar = new Bar();
Foo oFoo = oBar;

oFoo.ListObject.Add("Item");
// oFoo.ListObject= { "Item" }
// oBar.ListString = { "Item" }

oBar.ListString.Add("NewItem");
// oFoo.ListObject= { "Item" }
// oBar.ListString = { "Item" }

如您所见,使用基类对象可以很好地工作(一个项目被添加到内部列表),但使用派生类对象不起作用。我知道原因是因为将列表强制转换为列表实际上会创建列表的新副本并返回该副本。我想知道是否有可能编写这些类,使其双向工作。

您可以尝试以下方法:

public abstract class Foo<T>
{
    List<T> _List = new List<T>();
    public List<T> ListObject { get { return _List; } }
}
public class Bar : Foo<string>
{
    public List<string> ListString
    {
        get { return ListObject; }
    }
}
公共抽象类Foo
{
列表_List=新列表();
公共列表ListObject{get{return}
}
公共类酒吧:富
{
公共列表列表字符串
{
获取{return ListObject;}
}
}
结果:

您可以尝试以下方法:

public abstract class Foo<T>
{
    List<T> _List = new List<T>();
    public List<T> ListObject { get { return _List; } }
}
public class Bar : Foo<string>
{
    public List<string> ListString
    {
        get { return ListObject; }
    }
}
公共抽象类Foo
{
列表_List=新列表();
公共列表ListObject{get{return}
}
公共类酒吧:富
{
公共列表列表字符串
{
获取{return ListObject;}
}
}
结果:
如果您不喜欢上面的通用解决方案,可以将
列表
成员抽象化

public abstract class Foo
{
    public abstract IList ListObject { get; }
}

public class Bar : Foo
{
    public override IList ListObject
    {
        get { return new List<string>(); }
    }
}
公共抽象类Foo
{
公共抽象IList ListObject{get;}
}
公共类酒吧:富
{
公共覆盖IList ListObject
{
获取{返回新列表();}
}
}

如果您不喜欢上面的通用解决方案,可以将
列表
成员抽象化

public abstract class Foo
{
    public abstract IList ListObject { get; }
}

public class Bar : Foo
{
    public override IList ListObject
    {
        get { return new List<string>(); }
    }
}
公共抽象类Foo
{
公共抽象IList ListObject{get;}
}
公共类酒吧:富
{
公共覆盖IList ListObject
{
获取{返回新列表();}
}
}
公共抽象类Foo
{
公共抽象IList MyList{get;}
//即使MyList是在继承的类中定义的,也可以在此类中操作它
}
公共类酒吧:富
{
私有只读IList_myList=new List();
公共重写IList MyList
{
获取{return\u myList;}
}
}
[测试夹具]
公共类TestFixture1
{
[测试]
公开无效测试()
{
Bar oBar=新的Bar();
Foo-oFoo=oBar;
oFoo.MyList.添加(“项目”);
//oFoo.ListObject={“Item”}
//oBar.ListString={“项”}
oBar.MyList.Add(“新项目”);
//oFoo.ListObject={“Item”}
//oBar.ListString={“项”}
}
}
公共抽象类Foo
{
公共抽象IList MyList{get;}
//即使MyList是在继承的类中定义的,也可以在此类中操作它
}
公共类酒吧:富
{
私有只读IList_myList=new List();
公共重写IList MyList
{
获取{return\u myList;}
}
}
[测试夹具]
公共类TestFixture1
{
[测试]
公开无效测试()
{
Bar oBar=新的Bar();
Foo-oFoo=oBar;
oFoo.MyList.添加(“项目”);
//oFoo.ListObject={“Item”}
//oBar.ListString={“项”}
oBar.MyList.Add(“新项目”);
//oFoo.ListObject={“Item”}
//oBar.ListString={“项”}
}
}

我希望其他人能给出一个合理的好答案,但现实是,这个问题可能没有一个好答案

然而,有几种方法可以剥普通猫的皮,其中很多都很难看

这个问题的一个丑陋的解决方案是实现一个list类,它封装了n
list
对象,并尝试以您选择的任何类型访问对象。这种类型的代理类可能很难正确使用,但可能是实现您正试图实现的功能的一种方法

public class StringObjectList : IList<string>
{
    private List<object> _list;
    public StringObjectList(List<object> src)
    {
        _list = src;
    }

    // IList Implementation...

    public string this[int index]
    {
        get
        {
            object obj = _list[index];
            if (obj == null)
                return null;
            return obj.ToString();
        }
        set
        {
            _list[index] = value;
        }
    }

    // ... plus 3 more IList<string> methods (IndexOf, Insert, RemoveAt)

    // ICollection<string> implementation (5 methods, 2 properties)

    // IEnumerable<string> implementation (1 method)

    // IEnumerable implementation (1 method)
}
您可能遇到的问题是
IEnumerable
IEnumerable
实现,这可能需要您创建几个支持类


不简单,不优雅,但可能可行。

我希望其他人能给出一个合理的好答案,但现实是,这个答案可能没有好答案

然而,有几种方法可以剥普通猫的皮,其中很多都很难看

这个问题的一个丑陋的解决方案是实现一个list类,它封装了n
list
对象,并尝试以您选择的任何类型访问对象。这种类型的代理类可能很难正确使用,但可能是实现您正试图实现的功能的一种方法

public class StringObjectList : IList<string>
{
    private List<object> _list;
    public StringObjectList(List<object> src)
    {
        _list = src;
    }

    // IList Implementation...

    public string this[int index]
    {
        get
        {
            object obj = _list[index];
            if (obj == null)
                return null;
            return obj.ToString();
        }
        set
        {
            _list[index] = value;
        }
    }

    // ... plus 3 more IList<string> methods (IndexOf, Insert, RemoveAt)

    // ICollection<string> implementation (5 methods, 2 properties)

    // IEnumerable<string> implementation (1 method)

    // IEnumerable implementation (1 method)
}
您可能遇到的问题是
IEnumerable
IEnumerable
实现,这可能需要您创建几个支持类


不简单,不优雅,但可能是可行的。

我认为只有使用
dynamic
s才能做到这一点,不是吗?在内部使用动态对象…此代码编译并在C#5/.NET4.5上工作。那么问题出在哪里呢?请注意,当添加到ListString时,您不是添加到_List,而是添加到一个新的动态创建的列表中。如果您试图将
List
转换到子类中的
List
,我会提醒您,这在最好的情况下是不明智的,在最坏的情况下是极其糟糕的编程。您的最终目标是什么?您似乎想学习一些东西,而不是实现生产代码?更清楚你在想什么?@Vercas。。动态嗯,我需要看看,因为我从来没听说过我认为只有使用
dynamic
s才能实现这一点,不是吗?在内部使用动态对象…此代码编译并在C#5/.NET4.5上工作。那么问题出在哪里呢?请注意,当添加到ListString时,您不是添加到_List,而是添加到一个新的动态创建的列表中。如果您试图将
List
转换到子类中的
List
,我会提醒您,这在最好的情况下是不明智的,在最坏的情况下是极其糟糕的编程。你的最终目标是什么?你似乎想离开