一个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
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>可以更方便地获取集合中元素的数量,而不需要遍历整个集合。这样可以提高代码的效率。