chatGPT帮忙解决一个百度不到答案的IReadOnlyCollection`1未定义或导入的问题

一个c#老项目,不知道是因为什么时候批量替换了csproj的内容,还是因为我升级了vs每个升级版导致的。
目前Visual Studio Community 2022 (64位) -Preview 版本17.5.0 Preview 5.0
代码如下:

private LinkedList<IfCondNode> m_Children =new LinkedList<IfCondNode>();
public IEnumerable<IfCondNode> Children
{
    get
    {
        return (IEnumerable < IfCondNode >)m_Children;
    }
}

  



错误信息为:

error CS0518: 预定义类型“System.Collections.Generic.IReadOnlyCollection`1”未定义或导入

 


问了半天百度,都是说obj目录删除之类的无用的话。还有说是.net framework 4.0文件损坏,让重装的,没有敢试。

问了一下chatGPT,这个类型是在.net framework 4.5的mscorelib.dll中定义的,而且这个dll是c#的内核dll,不能在项目中选择性的引用。
测试了一下切换.net framework版本号为4.5之后果然就好了。但是我其它项目都用这个dll啊,而且还要发布给win xp用。
转到了LinkedList<T>的定义(程序集 System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089),
果然集成了一个颜色为黑色(vs反射功能找不到)的IReadOnlyCollection<T>,而且往IEnumerable<T>强制转换的时候是先转换成这个类型,再转换。

问chatGPT我就想在.net framework 4下面用,有什么办法。
它提了三个办法,其中第三个挺靠谱的,(第二个是把4.5的代码拷过来,也可以,但是碰到了一个宏的问题)。
增加了一个助手类之后,代码变为:

private MyLinkList<IfCondNode> m_Children =new MyLinkList<IfCondNode>( new LinkedList<IfCondNode>());
//旧插入的方法
//m_Children.AddFirst(item);
//新插入成员的方法变成了
m_Children.d.AddFirst(item);

  

助手类内容如下:

#if NET40
//public interface IReadOnlyCollection<out T>
//{
// int Count { get; }
// IEnumerator<T> GetEnumerator();
//}
#endif

//public interface IReadOnlyDictionary<TKey, TValue> : IReadOnlyCollection<KeyValuePair<TKey, TValue>>
//{
// TValue this[TKey key] { get; }
// IEnumerable<TKey> Keys { get; }
// IEnumerable<TValue> Values { get; }
// bool ContainsKey(TKey key);
// bool TryGetValue(TKey key, out TValue value);
//}
public class MyLinkList<T> : IEnumerable<T> //LinkedList<T> //, IReadOnlyCollection<T>,IEnumerable<T>
{
//int IReadOnlyCollection<T>.Count
//{
// get
// {
// return this.Count;
// }
//}
// IEnumerator<T> IReadOnlyCollection<T>.GetEnumerator()
// {
// return this.GetEnumerator();
//}
IEnumerator<T> IEnumerable<T>.GetEnumerator()
{
return d.GetEnumerator();
}

public IEnumerator GetEnumerator()
{
return d.GetEnumerator();
}

public LinkedList<T> d = null;
public MyLinkList(LinkedList<T> old)
{
d=old;
}
}

public class MySortedList<TKey, TValue> : IDictionary<TKey, TValue> //LinkedList<T> //, IReadOnlyCollection<T>,IEnumerable<T>
{
IEnumerator<KeyValuePair<TKey, TValue>> IEnumerable<KeyValuePair<TKey, TValue>>.GetEnumerator()
{
return d.GetEnumerator();
}

public IEnumerator GetEnumerator()
{
return d.GetEnumerator();
}

public bool ContainsKey(TKey key)
{
return d.ContainsKey(key);
}

public void Add(TKey key, TValue value)
{
d.Add(key, value);
}

public bool Remove(TKey key)
{
return d.Remove(key);
}

public bool TryGetValue(TKey key, out TValue value)
{
return d.TryGetValue(key, out value);
}

public void Add(KeyValuePair<TKey, TValue> item)
{
d.Add(item.Key, item.Value);
}

public void Clear()
{
d.Clear();
}

public bool Contains(KeyValuePair<TKey, TValue> item)
{
return d.ContainsKey(item.Key);// && d[item.Key]==item.Value;
}

public void CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex)
{
foreach (var x in d)
{
array[arrayIndex++] = x;
}
}

public bool Remove(KeyValuePair<TKey, TValue> item)
{
return d.Remove(item.Key);
}

public SortedList<TKey, TValue> d;

public ICollection<TKey> Keys => d.Keys;

public ICollection<TValue> Values => d.Values;

public int Count => d.Count;

public bool IsReadOnly => false;// d.IsReadOnly;

public TValue this[TKey key] { get => d[key]; set => d[key] = value; }

public MySortedList(SortedList<TKey, TValue> old)
{
d = old;
}
}

 另外,请教了一下chatGPT一下,不知道对不对

Q:为什么LinkedList<T> 转IEnumerable<T>的时候,先转换为IReadOnlyCollection<T> ?

A:在C#中,IEnumerable<T>是一个非常基础的接口,它只提供了一个方法GetEnumerator(),用于返回一个IEnumerator<T>对象,该对象可以用于迭代集合中的元素。而IReadOnlyCollection<T>接口继承自IEnumerable<T>,并添加了Count属性,该属性返回集合中元素的数量。因此,将LinkedList<T>转换为IReadOnlyCollection<T>可以更方便地获取集合中元素的数量,而不需要遍历整个集合。这样可以提高代码的效率。

 

posted @ 2023-03-26 10:04  william1994  阅读(51)  收藏2(0