我有这个结构
[Serializable]
public struct Foo : IConvertible, IXmlSerializable, IComparable, IComparable<Foo>
{
private readonly int _value;
private Foo(int id)
{
this._value = id;
}
private IConvertible ConvertibleValue
{
get
{
return this._value;
}
}
public int CompareTo(object obj)
{
if (obj is Foo)
{
var foo = (Foo) obj;
return this.CompareTo(foo);
}
return -1;
}
public int CompareTo(Foo other)
{
return this._value.CompareTo(other._value);
}
public TypeCode GetTypeCode()
{
return this._value.GetTypeCode();
}
bool IConvertible.ToBoolean(IFormatProvider provider)
{
return this.ConvertibleValue.ToBoolean(provider);
}
char IConvertible.ToChar(IFormatProvider provider)
{
return this.ConvertibleValue.ToChar(provider);
}
sbyte IConvertible.ToSByte(IFormatProvider provider)
{
return this.ConvertibleValue.ToSByte(provider);
}
byte IConvertible.ToByte(IFormatProvider provider)
{
return this.ConvertibleValue.ToByte(provider);
}
short IConvertible.ToInt16(IFormatProvider provider)
{
return this.ConvertibleValue.ToInt16(provider);
}
ushort IConvertible.ToUInt16(IFormatProvider provider)
{
return this.ConvertibleValue.ToUInt16(provider);
}
int IConvertible.ToInt32(IFormatProvider provider)
{
return this.ConvertibleValue.ToInt32(provider);
}
uint IConvertible.ToUInt32(IFormatProvider provider)
{
return this.ConvertibleValue.ToUInt32(provider);
}
long IConvertible.ToInt64(IFormatProvider provider)
{
return this.ConvertibleValue.ToInt64(provider);
}
ulong IConvertible.ToUInt64(IFormatProvider provider)
{
return this.ConvertibleValue.ToUInt64(provider);
}
float IConvertible.ToSingle(IFormatProvider provider)
{
return this.ConvertibleValue.ToSingle(provider);
}
double IConvertible.ToDouble(IFormatProvider provider)
{
return this.ConvertibleValue.ToDouble(provider);
}
decimal IConvertible.ToDecimal(IFormatProvider provider)
{
return this.ConvertibleValue.ToDecimal(provider);
}
DateTime IConvertible.ToDateTime(IFormatProvider provider)
{
return this.ConvertibleValue.ToDateTime(provider);
}
string IConvertible.ToString(IFormatProvider provider)
{
return this.ConvertibleValue.ToString(provider);
}
object IConvertible.ToType(Type conversionType, IFormatProvider provider)
{
return this.ConvertibleValue.ToType(conversionType, provider);
}
XmlSchema IXmlSerializable.GetSchema()
{
return null;
}
void IXmlSerializable.ReadXml(XmlReader reader)
{
var stringId = reader.ReadElementContentAsString();
if (string.IsNullOrEmpty(stringId))
{
return;
}
this = int.Parse(stringId);
}
void IXmlSerializable.WriteXml(XmlWriter writer)
{
writer.WriteValue(this);
}
public static implicit operator int(Foo value)
{
return value._value;
}
public static implicit operator Foo(int value)
{
Foo foo;
if (value > 0)
{
foo = new Foo(value);
}
else
{
foo = new Foo();
}
return foo;
}
public override string ToString()
{
return this._value.ToString();
}
}
现在我失败了:
var intList = new List<int>
{
1,
2,
3,
4
};
var fooList = intList.Cast<Foo>().ToList();
与
System.InvalidCastException:指定的强制转换无效。 在System.Linq.Enumerable.d__aa`1.MoveNext() 在System.Collections.Generic.List`1..ctor(IEnumerable`1集合) 在System.Linq.Enumerable.ToList [TSource](IEnumerable`1 source) ...
答案 0 :(得分:10)
原因是Cast
函数是针对泛型类型(即非具体类型)编写的。它看起来有点像下面的
public IEnumeralbe<T> Cast<T>(this IEnumerable source) {
foreach (object cur in source) {
yield return (T)cur;
}
}
Cast
内的强制转换操作只能在此通用信息上完成,该信息不包括Foo
上的特殊投射操作符。因此,此代码不考虑隐式转换,而基本上仅依赖于CLR转换。
为了使其正常工作,您需要直接针对Foo
类型进行强制转换。最好的方法是选择
var fooList = intList.Select(x => (Foo)x).ToList();