当我将值传递给int
变量,其值超过int
的最大值时,int
变量的值变为0
。
我使用以下步骤来检索我的数据。我不使用任何try-catch块而不抛出异常。
在我的 WCF服务中,我使用DataTable
IBM.Data.DB2.iSeries.iDB2DataAdapter.Fill(DataSet)
然后我使用代码将DataTable
转换为List<T>
:
public static List<T> DataTableToList<T>(DataTable dt)
{
List<T> tableEntity = new List<T>();
foreach (DataRow row in dt.Rows)
{
T rowEntity = Activator.CreateInstance<T>();
rowEntity.GetType().GetProperties().Where(o => dt.Columns.OfType<DataColumn>()
.Select(p => p.ColumnName).Contains(o.Name)).ToList()
.ForEach(o => o.SetValue(rowEntity, row[o.Name], null));
tableEntity.Add(rowEntity);
}
return tableEntity;
}
类型:
public class Client
{
public int ID { get; set; }
public string Name { get; set; }
}
我使用WCF服务方法返回它:
[OperationContract]
public string GetClients()
{
List<Client> clients = new DB().RetrieveClients();
return Tools.SerializeObjectToXML<List<Client>>(clients);
}
使用辅助方法进行序列化:
public static string SerializeObjectToXML<T>(T item)
{
XmlSerializer xs = new XmlSerializer(typeof(T));
using (StringWriter writer = new StringWriter())
{
xs.Serialize(writer, item);
return writer.ToString();
}
}
然后在客户端应用程序中,我使用 WSHttpBinding 的默认绑定从服务参考中检索它,代码为:
List<Client> clients = Tools.DeserializeXMLToObject<List<Client>>(new SomeServiceClient().GetClients());
使用反序列化的辅助方法:
public static T DeserializeXMLToObject<T>(string xmlText)
{
if (string.IsNullOrEmpty(xmlText)) return default(T);
XmlSerializer xs = new XmlSerializer(typeof(T));
using (MemoryStream memoryStream = new MemoryStream(new UnicodeEncoding().GetBytes(xmlText)))
using (XmlTextReader xsText = new XmlTextReader(memoryStream))
{
xsText.Normalization = true;
return (T)xs.Deserialize(xsText);
}
}
当您从 double 或 float 值转换为整数类型时,该值将被截断。如果结果积分值超出目标值的范围,则结果取决于溢出检查上下文。在已检查的上下文中,抛出了OverflowException,而在未经检查的上下文中,结果是未指定的目标类型值。
Client.ID
的值变为0
?我的代码在C#,框架4中,在VS2010 Pro中构建。
请提前帮助,谢谢。
答案 0 :(得分:2)
这里有一些可疑的东西。 SetValue
不会进行演员/转换(甚至不会从uint
到int
,只是经过测试)。您可以更好地扩展真实ForEach
中的foreach
代码并进行调试。
例如:
foreach (var o in rowEntity.GetType().GetProperties().Where(o => dt.Columns.OfType<DataColumn>()
.Select(p => p.ColumnName).Contains(o.Name)))
{
if (o.Name == "ID")
{
// Put a breakpoint here
}
o.SetValue(rowEntity, row[o.Name], null));
}
答案 1 :(得分:1)
默认情况下,Visual Studio中的算术溢出编译器开关已关闭。启用它:
答案 2 :(得分:1)
如果您选中或取消选中,我不确切知道您在哪里可以找到。但这取决于http://msdn.microsoft.com/en-us/library/khy08726(v=vs.100).aspx
中所述的编译器选项正如Thorsten Dittmar所说,您可以更好地使用DataContract轻松发送客户端。
如果它溢出,您可以更好地使用long
代替int
。这样它就有更多的位置(long == Int64
)。如果你所有的Id都是&gt; 0您可以使用unsigned int或unsigned long作为您的Id。无符号意味着不是数字低于零,而是仅为正数,因此是正数位置的两倍。
答案 3 :(得分:0)
只是一个问题:为什么要将列表作为字符串传输而不是执行以下操作:
[OperationContract]
public Client[] GetClients()
{
List<Client> clients = new DB().RetrieveClients();
return clients.ToArray();
}
并声明Client
类,如:
[DataContract]
public class Client
{
[DataMember]
public int ID;
[DataMember]
public string Name;
}
另外:如果数据库中ID
的类型允许的值大于Int32.MaxValue
,为什么你会使用Int32
而不是Int64
?< / p>
关于溢出检查:我知道使用Convert.ToInt32(Int64.MaxValue);
会引发异常,int i = (int)Int64.MaxValue
则不会。