我正在使用 aLinkedHashMap<Integer, Integer>来存储 2D 游戏中图块上的图层值。较高的数字覆盖较低的数字。
在我的绘制函数中,我迭代设置的值并绘制每个值。这意味着我要(width * height * numLayers)多次拆箱价值观。我计划移植到 Android,因此我希望尽可能高效,但我认为这太多了?
我使用地图的原因是因为层数(键)很重要:4 以上的键是在玩家上方绘制的,等等。所以我经常需要跳过一堆键。
我可能可以只使用 an,int[10]因为我不需要那么多层,但是与我当前的 HashMap 相比,所有未使用的层都会占用 32 位,而我当前的 HashMap 可以有键 0、9,只占用 64 位位。
我刚刚将一个代码片段从VB.NET转换为C#,并偶然发现了这个问题.
考虑以下代码:
Dim x As Integer = 5
Dim y As Object = x
Dim z As Decimal = CType(y, Decimal)
Run Code Online (Sandbox Code Playgroud)
编译器或运行时没有错误.z是五.
现在让我们将此代码翻译为C#
int x = 5;
object y = x;
decimal z = (decimal)y;
Run Code Online (Sandbox Code Playgroud)
编译器没有错误,但在运行时抛出异常:
Cannot unbox "y" to "decimal"
Run Code Online (Sandbox Code Playgroud)
现在我的问题是,这将是最聪明的C#方式.
目前我的代码看起来像.
int x = 5;
object y = x;
decimal z = decimal.Parse(y.ToString());
Run Code Online (Sandbox Code Playgroud)
但另一种解决方案是:
decimal z = (decimal)(int)y;
Run Code Online (Sandbox Code Playgroud)
这看起来有点混乱,但可能比decimal.Parse更少开销.
几个月前我参加了一个研讨会,发言人声明自从.NET 1.1以来,装箱或拆箱操作的总成本已经降低.我查看了我的(差)注释,无法确定此语句是否引用了box和unbox指令,或者引用了类(即泛型类型),使得装箱/拆箱不太可能发生.
.NET 1.1和.NET 4.0之间的CLR拳击相关指令是否有性能改进,如果是这样,我在哪里可以找到有关显示收益的测量信息?
嘿伙计们,我有这个sql参数我得到了不能作为int错误的unbox
returnValue = (int)cmdUpdateCreatedOn.Parameters["@intcount"].Value;
Run Code Online (Sandbox Code Playgroud)
返回值声明为int returnValue = 0,我的参数也声明为int,它正在更新行的行数.我尝试过不同的转换语法似乎没有用.
我的SP是
ALTER Procedure [dbo].[UpdateStation]
@intcount int output AS
select StationaryName into #stname from Stationaries where Authorized = 0
select * from #stname
Update Stationaries Set Authorized = 1 where Authorized = 0 set @intcount = @@rowcount
Run Code Online (Sandbox Code Playgroud) 比方说,我在c#中有以下代码
int x = 0;
x.ToString();
Run Code Online (Sandbox Code Playgroud)
这内部是否做了拳击x?有没有办法从视觉工作室看到这种情况?
为什么这样做:
decimal dec = new Decimal(33);
double dd = (double) dec;
Console.WriteLine(dd);
Run Code Online (Sandbox Code Playgroud)
但不是这个:
decimal dec = new Decimal(33);
object o = (object)dec;
double dd = (double) o;
Console.WriteLine(dd);
Run Code Online (Sandbox Code Playgroud)
第二个例子抛出:
System.InvalidCastException:指定的强制转换无效.
这个问题来自我有一个通用方法的情况
public T GetValue(string q)
Run Code Online (Sandbox Code Playgroud)
从数据源获取值.这些值的类型是未知的,但该方法假定它可以将值转换为T.有时,值将是对象{decimal},T将是double,在这种情况下将抛出InvalidCastException.但原则上这不应该是一个问题,因为值是一个小数(虽然是一个对象的盒子),可以强制转换为double.
我该如何处理这个问题呢?
概述(请原谅我如此详细,但我宁愿它太多而不是太少):我正在尝试以这样的方式编辑Dapper源代码,以便从数据库中读取任何DateTime或Nullable ,其DateTime.Kind属性始终设置为DateTimeKind.Utc.
在我们的系统中,来自前端的所有DateTime都保证是UTC时间,并且数据库(Sql Server Azure)将它们存储为UTC中的DateTime类型(我们不使用DateTimeOffsets,我们总是确保DateTime在将其存储在数据库中之前是UTC.)
我一直在阅读有关如何使用ILGenerator.Emit(...)生成DynamicMethods代码的所有内容,并且感觉我对它如何与评估堆栈,本地人等一起工作有很好的理解.在我努力解决这个问题问题,我已经编写了一些代码示例,以帮助我实现最终目标.我写了一个DynamicMethod来取一个DateTime作为参数,调用DateTime.SpecifyKind,返回值.然后与DateTime相同?type,使用其Nullable.Value属性获取SpecifyKind方法的DateTime.
这就是我的问题所在:在dapper中,DateTime(或DateTime?我实际上并不知道,但是当我把它视为我要么得不到我想要的时候)是盒装的.所以,当我尝试使用OpCodes.Unbox或OpCodes.Unbox_Any,然后把结果作为要么日期时间或日期时间?我得到一个VerificationException:操作可能会破坏运行.
显然我错过了一些关于拳击的重要内容,但我会给你我的代码示例,也许你可以帮助我让它工作.
这有效:
[Test]
public void Reflection_Emit_Test3()
{
//Setup
var dm = new DynamicMethod("SetUtc", typeof(DateTime?), new Type[] {typeof(DateTime?)});
var nullableType = typeof(DateTime?);
var il = dm.GetILGenerator();
il.Emit(OpCodes.Ldarga_S, 0); // [DateTime?]
il.Emit(OpCodes.Call, nullableType.GetProperty("Value").GetGetMethod()); // [DateTime]
il.Emit(OpCodes.Ldc_I4, (int)DateTimeKind.Utc); // [DateTime][Utc]
il.Emit(OpCodes.Call, typeof(DateTime).GetMethod("SpecifyKind")); //[DateTime]
il.Emit(OpCodes.Newobj, nullableType.GetConstructor(new[] {typeof (DateTime)})); //[DateTime?]
il.Emit(OpCodes.Ret);
var meth = (Func<DateTime?, DateTime?>)dm.CreateDelegate(typeof(Func<DateTime?, DateTime?>));
DateTime? now = DateTime.Now;
Assert.That(now.Value.Kind, Is.Not.EqualTo(DateTimeKind.Utc));
//Act
var nowUtc = meth(now);
//Verify
Assert.That(nowUtc.Value.Kind, Is.EqualTo(DateTimeKind.Utc));
}
Run Code Online (Sandbox Code Playgroud)
我得到了我期望的东西.好极了!但它还没有结束,因为我们已经拆箱了......
[Test]
public void Reflection_Emit_Test4()
{ …Run Code Online (Sandbox Code Playgroud) 我正在研究Joseph Albahari和Ben Albahari在Cuts 5.0中的拳击和拆箱主题.版权所有2012 Joseph Albahari和Ben Albahari,978-1-449-32010-2,但我需要扩展知识的深度,我找到了MSDN文章:Boxing and Unboxing(C#编程指南),我就找到了这个示例代码(显然与主题没有内在联系):
Console.WriteLine (String.Concat("Answer", 42, true));
Run Code Online (Sandbox Code Playgroud)
一旦执行,它将返回:
Answer42True
Run Code Online (Sandbox Code Playgroud)
为什么会出现字面上的'true'(与'false'相同)?
执行测试.
提前致谢.
在该SO交我发现它返回一个默认值,如果由读出的值的通用扩展方法SqlDataReader是null或DBNull.Value,和正确地转换值否则.我这样实现了:
public static T GetValueOrDefault<T>(this SqlDataReader reader, string columnName, T defaultValue = default(T))
{
object val = reader[columnName];
if (val == null || val == DBNull.Value)
{
return defaultValue;
}
return (T)val;
}
Run Code Online (Sandbox Code Playgroud)
下面提到的示例在上面链接的帖子中没有使用正确的语法,但是仍然建议这也适用于可空类型,例如int?.
但是,我int从数据库中读取了一个可以为空的列,如下所示:
MyProperty = reader.GetValueOrDefault<int?>("SomeColumnName")
Run Code Online (Sandbox Code Playgroud)
其中,调试模式让我发现,val是-1和T是int?,但我得到一个InvalidCastException.从这篇文章中我发现这是因为拆箱和铸造不能在一次操作中执行(val具有object保持short值的类型),但是我能做些什么来使它在我的情况下工作?由于它是一种通用方法,我不知道在进行转换之前如何手动取消它.
我有盒装元组:
(int, string) tuple = (1, "abc");
object box = tuple;
Run Code Online (Sandbox Code Playgroud)
如何从中获取元组box?强制object返回元组的正确语法是什么?
我的尝试:
var deconstruct = (int, string)box;
Run Code Online (Sandbox Code Playgroud)
显然是错误的:
错误CS1525无效的表达式术语'int'
错误CS1525无效的表达式术语“字符串”
错误CS1002; 预期
错误CS0201仅赋值,调用,递增,递减,等待和新对象表达式可以用作语句
unboxing ×10
c# ×9
boxing ×4
.net ×2
casting ×2
generics ×2
android ×1
autoboxing ×1
c#-7.0 ×1
clr ×1
dapper ×1
java ×1
parameters ×1
tuples ×1
value-type ×1