0

如何通过实现 Array Wrapper 来最小化开销?

1 为MyProviderInfos选择哪种接口/类型?

2使用私有静态枚举器是否合理?不,从 答案

3 MyProviderInfos是否应该是一个属性以及如何保护其成员不被修改?成员的内部/私人SETTERS(来自相同的答案)

我尝试阅读有关 ICollection、Readonly-Collection、List、IList、Array 的 SO 文章,但仍然对最适合该场景的内容感到困惑:

  • Array MyProviderInfos 由编译时形成,不会(不得)在运行时更改。
  • 该类(必须)是可枚举的(使用数组 MyProviderInfos 的元素)并且不需要自定义列表函数(.Add .Remove)。
  • 该类具有使用 Array 的静态函数。
  • 类必须是非静态的才能支持索引。

代码:

 public class MyIdentifiers : IEnumerable<MyProviderInfo>
 {
   //public static IList<MyProviderInfo> getMyProviderInfos() 
   //{ return MyProviderInfos; }

    public static int MyProviderCount()
    {
        return MyProviderInfos.Count;
    }

    public static readonly IList<MyProviderInfo> MyProviderInfos = new[]
    {
        new MyProviderInfo
            {
                MyProvider = MyProvider.FirstProvider,
                Url = "https://www.google.com",                       
            }
    };

    private static IEnumerator<MyProviderInfo> _enumerator = 
((IEnumerable<MyProviderInfo>)MyProviderInfos).GetEnumerator();

    public IEnumerator<MyProviderInfo> GetEnumerator()
    {
        return _enumerator;
        //return ((IEnumerable<MyProviderInfo>)MyProviderInfos).GetEnumerator();
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }

}
4

1 回答 1

1

为 MyProviderInfos 选择哪种接口/类型?

除非您想限制用户直接可见的功能,否则您应该始终返回不太通用的类型(在您的情况下是数组本身)。

作为一般规则,接受最通用的可能类型作为参数是一种好习惯(例如,如果您只想枚举一个集合,然后将该参数声明为IEnumerable<T>)并将不太通用的类型作为结果(因此用户可以像IEnumerable<T>只需要一样使用它that 或 as IList<T>,根据需要,没有脆弱的演员表和转换)。此外,在您的情况下,IList<T>支持添加项目,但这将在运行时抛出,因为数组是固定大小的,因此您公开的内容超出了他们实际可以做的事情。

例如:

string[] ConvertToTitleCase(IEnumerable<string> names);

当然,您可以返回 an IEnumerable<string>too 而不是string[],如果 - 例如 - 实现没有为结果创建任何数组以避免额外的转换,它可能是合适的。

使用私有静态枚举器是否合理?

绝对不,枚举器是一个具有状态的对象(查看任何IEnumerator<T>实现)然后它不能是静态的(例如,当被不同的线程调用时想象一下)。

MyProviderInfos 是否应该是一个属性以及如何保护其成员不被修改?

除非您想提供某种延迟初始化,否则它不需要是属性。为了保护它的成员,你唯一能做的就是使它们成为只读的(如果集合本身是只读的并不重要)。如何做到这一点取决于MyProviderInfo实施。您可以考虑不public为其属性公开任何设置器。例如:

class MyProviderInfo
{
    public MyProviderInfo(Provider provider, string url)
    {
        Provider = provider;
        Url = url;
    }

    public Provider Provider
    {
        get;
        private set;
    }

    public string Url
    {
        get;
        private set;
    }
}

或者,无需太多更改,保留现有代码,但将 setter 设置为内部(因此您的库的用户将无法修改它们):

class MyProviderInfo
{
    public Provider Provider
    {
        get;
        internalset;
    }

    public string Url
    {
        get;
        internal set;
    }
}

总结一下,我将其重写为:

 public class MyIdentifiers : IEnumerable<MyProviderInfo>
 {
    public int Count
    {
        get { return _myProviderInfos.Count; }
    }

    public IEnumerator<MyProviderInfo> GetEnumerator()
    {
        return ((IEnumerable<MyProviderInfo>)_myProviderInfos ).GetEnumerator();
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }

    private static readonly IList<MyProviderInfo> _myProviderInfos = new[]
    {
        new MyProviderInfo
            {
                MyProvider = MyProvider.FirstProvider,
                Url = "https://www.google.com",                       
            }
    };
 }
于 2012-11-14T12:01:56.757 回答