【问题标题】:How can I create class which is just List<string> with some custom methods?如何使用一些自定义方法创建只是 List<string> 的类?
【发布时间】:2015-05-05 12:16:58
【问题描述】:

这似乎是一项微不足道的任务,但我不知道该怎么做(也不知道该怎么称呼它)。

示例。我需要state 类,这实际上只是字符串列表。它必须这样工作:

state s = new state();
s.Add("John Madden");
//s[0] == "John Madden"

而且我需要在这个类中添加一些方法。

【问题讨论】:

  • 你可以让State实现IList&lt;string&gt;
  • 您可以创建自己的自定义集合并使用自定义方法丰富它。 msdn.microsoft.com/en-us/library/xth2y6ft(v=vs.71).aspx
  • state 本身是否必须代表一个列表?还是可以封装一个?
  • 如果你的类真的只是一个List&lt;string&gt;,那么也许你真正想做的就是继续使用List&lt;string&gt;,而不是定义你自己的类。 “自定义方法”可以只是扩展方法。不幸的是,您的问题对于这些“自定义方法”到底是什么以及为什么您觉得您想要一个专用于 State 对象的类相当模糊。

标签: c# oop


【解决方案1】:

你可以继承它:

public class State : List<string>
{}

这样,您就拥有了List&lt;string&gt; 提供的完整界面,以及您自己的类型名称。然后你就可以去添加你自己的方法了。

如果您想对其进行更多控制,例如要隐藏某些方法或更改它们的工作方式,您还可以创建一个实现 IList&lt;string&gt; 的包装类,并将其大部分方法委托给私有 List&lt;string&gt; 实例。例如。像这样:

public class State : IList<string>
{
    private List<string> internalList = new List<string>();

    public string this[int index]
    {
        get { return internalList[index]; }
        set { internalList[index] = value; }
    }

    public void Add (string item)
    {
        internalList.Add(item);
    }

    // etc. for the other IList<T> members
}

【讨论】:

  • 有了这个,你甚至可以通过构造函数让列表自己填充this.Add("")
  • List&lt;T&gt; 继承是个坏主意。 Why not inherit from List<T>
  • @SriramSakthivel,我完全不明白这有什么不好?
  • @InfernumDeus 阅读给定链接中的答案。你会意识到的。
  • @SriramSakthivel,我有一个很小的项目,状态实际上是一些其他对象的列表,所以我没有看到问题。从 List 继承看起来不错,因为它的解决方案非常短。
【解决方案2】:

我会选择封装一个列表,而不是继承一个列表(为什么可以找到here的一个重要原因)。

如果您需要让State 持有自定义的、状态相关的方法,它们与List&lt;string&gt; 派生类无关。

public class State
{
    public List<string> FooBar { get; set; }

    public void Foo() { }
    public void Bar() { }
}

【讨论】:

  • 我同意封装通常是一种更好的方法,但我不一定同意 Eric 回答的观点——事实上,试图在类和它们的“现实生活”对应物之间建立直接的相似之处并推导出这些相似之处的技术解决方案通常弊大于利——这种事情通常应该根据其技术优点而不是语义来考虑。我敢肯定,纯粹的 DDD 支持者会不同意我的观点,但你去吧。
  • @AntP 没关系,我们不必同意。我只是认为在 List&lt;T&gt; 的继承者上使用与 List&lt;T&gt; 没有直接关系的自定义方法会感觉很奇怪。
  • 我不同意这一点——这只是很好的封装。我只是认为您链接到的其他答案的基础过于专注于根据域语义得出技术决策,而不是实际的技术价值。
  • @InfernumDeus 从List&lt;string&gt; 继承的对象的公共合约看起来会更糟(在我的状态对象上使用 LINQ 有什么作用?)并且暴露的方式超出了您的需要。封装列表的对象将具有包含方法和属性的协定,这些方法和属性准确地解释了您应该如何与该对象交互(而不是能够通过您的状态对象调用 Aggregate())。
【解决方案3】:

尝试从Collection&lt;String&gt;继承,这是比使用List更好的方法:Collection versus List what should you use on your interfaces?

public class State : Collection<string>

List 并非旨在通过继承它来轻松扩展;它 旨在为内部实现快速。你会注意到 它上面的方法不是虚拟的,因此不能被覆盖,并且有 没有挂钩到它的添加/插入/删除操作。

【讨论】:

  • 这听起来更像是对@poke 答案的回复。本身不是答案。
  • @SriramSakthivel 答案本身很清楚:从 Collection 继承而不是 List
  • 问题是我不能从List&lt;string&gt;继承;如果是这样,那么您的答案 inherit from Collectioninstead from List 就可以了。另外,您在我发表评论后编辑了答案。
【解决方案4】:

我不知道您的确切要求,但也许坚持使用 List 并为您的附加功能使用扩展方法是一种合适的方法。

public static class ListExtensions 
{
    public static void DoSomethingWithMyStrings (this List<string> list)
    {
        // Implement your additional functionality here
    }
}

// Usage:
using ListExtensions;

var myList = new List<string>();
myList.Add("blah");
myList.DoSomethingWithMystrings ();

【讨论】:

  • 实际上我的类结构非常混乱,继承的类会使代码更清晰。但是谢谢你的提示!我可以在以后的项目中使用它。
猜你喜欢
  • 2012-12-29
  • 1970-01-01
  • 1970-01-01
  • 2021-07-28
  • 1970-01-01
  • 2013-02-16
  • 1970-01-01
  • 1970-01-01
  • 2011-12-21
相关资源
最近更新 更多