where T : struct
Run Code Online (Sandbox Code Playgroud)
我们C#开发人员都知道C#的基础知识.我的意思是声明,条件,循环,运算符等.
我们中的一些人甚至掌握了Generics,匿名类型,lambdas,LINQ等......
但是C#粉丝,瘾君子,专家几乎都不知道C#最隐藏的功能或技巧是什么?
yield由迈克尔·葡萄汁var由迈克尔·葡萄汁using()kokos的声明readonly由kokosas由迈克·斯通as/ is由埃德Swangrenas/ is(改进)由Rocketpantsdefault由deathofratsglobal::通过pzycomanusing()由块AlexCusevolatile作者:JakubŠturcextern alias作者:JakubŠturc我最近在使用一个DateTime对象,并写了这样的东西:
DateTime dt = DateTime.Now;
dt.AddDays(1);
return dt; // still today's date! WTF?
Run Code Online (Sandbox Code Playgroud)
intellisense文档AddDays()说它增加了一天的日期,它没有 - 它实际上返回添加了一天的日期,所以你必须写如下:
DateTime dt = DateTime.Now;
dt = dt.AddDays(1);
return dt; // tomorrow's date
Run Code Online (Sandbox Code Playgroud)
这个曾经多次咬过我,所以我认为编制最糟糕的C#陷阱会很有用.
我的测试机器上有一个非常奇怪的错误.错误是:
System.TypeLoadException: Method 'SetShort' in type 'DummyItem' from assembly 'ActiveViewers (...)' does not have an implementation.
我只是无法理解为什么.SetShort是否在DummyItem课堂上,我甚至重新编译了一个带有写入事件日志的版本,以确保它不是部署/版本问题.奇怪的是调用代码甚至不调用该SetShort方法.
以下代码确实可以满足我的需求,但它很难看,过多或者其他很多东西.我已经看过公式并尝试编写一些解决方案,但我最终得到了类似数量的陈述.
在这种情况下是否有一种数学公式可以使我受益,或者如果语句可以接受,那么它是16吗?
为了解释代码,这是一种基于同步回合的游戏.两个玩家每个都有四个动作按钮,结果来自一个数组(0-3),但变量'一'和'两个'可以是如果有帮助就分配任何东西 结果是,0 =既没有胜利,1 = p1胜利,2 = p2胜利,3 =双赢.
public int fightMath(int one, int two) {
if(one == 0 && two == 0) { result = 0; }
else if(one == 0 && two == 1) { result = 0; }
else if(one == 0 && two == 2) { result = 1; }
else if(one == 0 && two == 3) { result = 2; }
else if(one == 1 && two == 0) { result = 0; …Run Code Online (Sandbox Code Playgroud) 我很好奇其他人如何使用this关键字.我倾向于在构造函数中使用它,但我也可以在其他方法中使用它.一些例子:
在构造函数中:
public Light(Vector v)
{
this.dir = new Vector(v);
}
Run Code Online (Sandbox Code Playgroud)
别处
public void SomeMethod()
{
Vector vec = new Vector();
double d = (vec * vec) - (this.radius * this.radius);
}
Run Code Online (Sandbox Code Playgroud) 我对这个小C#quirk感到有点难过:
给定变量:
Boolean aBoolValue;
Byte aByteValue;
Run Code Online (Sandbox Code Playgroud)
以下编译:
if (aBoolValue)
aByteValue = 1;
else
aByteValue = 0;
Run Code Online (Sandbox Code Playgroud)
但这不会:
aByteValue = aBoolValue ? 1 : 0;
Run Code Online (Sandbox Code Playgroud)
错误说:"不能隐式地将类型'int'转换为'byte'."
当然,这个怪物会编译:
aByteValue = aBoolValue ? (byte)1 : (byte)0;
Run Code Online (Sandbox Code Playgroud)
这里发生了什么?
编辑:
使用VS2008,C#3.5
我们接管了一些.NET 1.1 Windows服务代码,它生成线程以从队列中读取消息(SeeBeyond eGate JMS队列,但这并不重要),然后生成线程来处理目标应用程序服务中的消息.我们不断遇到令我们困惑的逻辑和设计决策.这是一个示例,其中已从队列中检索消息(lsMessage)并准备好进行处理
if(lsMessage != null)
{
// Initialize a new thread class instance, pass in message
WorkerThread worker = new WorkerThread(lsMessage);
Process:
// Start a new thread to process the message
Thread targetWorker = new Thread(new ThreadStart(worker.ProcessMessage));
if(targetWorker != null)
{
targetWorker.Priority = ThreadPriority.Highest;
targetWorker.Name = "Worker " + queueKey.ToString();
targetWorker.Start();
// wait for worker thread to join back in specified period
bool isFinished = targetWorker.Join(SYNC_THREAD_TIMEOUT);
string message = worker.replyMsg;
if ( !isFinished ) // BF is …Run Code Online (Sandbox Code Playgroud) 请考虑以下事项:
var x = new Action(() => { Console.Write("") ; });
var y = new Action(() => { });
var a = x.GetHashCode();
var b = y.GetHashCode();
Console.WriteLine(a == b);
Console.WriteLine(x == y);
Run Code Online (Sandbox Code Playgroud)
这将打印:
True
False
Run Code Online (Sandbox Code Playgroud)
为什么哈希码相同?
这有点令人惊讶,并且会使代表的使用Dictionary速度与a List(也就是O(n)查找)一样慢.
更新:
问题是为什么.IOW谁做出这样一个(愚蠢的)决定?
一个更好的哈希码实现应该是:
return Method ^ Target == null ? 0 : Target.GetHashcode();
// where Method is IntPtr
Run Code Online (Sandbox Code Playgroud) 我很想知道为什么会这样.请阅读下面的代码示例以及每个部分下面的注释中发出的相应IL:
using System;
class Program
{
static void Main()
{
Object o = new Object();
o.GetType();
// L_0001: newobj instance void [mscorlib]System.Object::.ctor()
// L_0006: stloc.0
// L_0007: ldloc.0
// L_0008: callvirt instance class [mscorlib]System.Type [mscorlib]System.Object::GetType()
new Object().GetType();
// L_000e: newobj instance void [mscorlib]System.Object::.ctor()
// L_0013: call instance class [mscorlib]System.Type [mscorlib]System.Object::GetType()
}
}
Run Code Online (Sandbox Code Playgroud)
为什么编译器callvirt为第一部分发出a 而call第二部分发出a ?是否有任何理由编译器会发出callvirt非虚方法的指令?如果在某些情况下编译器将callvirt为非虚拟方法发出一个,这会产生类型安全问题吗?
我刚读完"Nutshell中的C#4.0"(O'Reilly),我认为这对于愿意转向C#的程序员来说是一本好书,但它让我感到疑惑.我的问题是using声明的定义.根据这本书(第138页),
using (StreamReader reader = File.OpenText("file.txt")) {
...
}
Run Code Online (Sandbox Code Playgroud)
恰好相当于:
StreamReader reader = File.OpenText("file.txt");
try {
...
} finally {
if (reader != null)
((IDisposable)reader).Dispose();
}
Run Code Online (Sandbox Code Playgroud)
但是,假设这是真的,并且此代码在单独的线程中执行.此线程现在已中止thread.Abort(),因此ThreadAbortException抛出a并假设线程正好在初始化读取器之后和输入try..finally子句之前.这意味着读者不会被处置!
一种可能的解决方案是以这种方式编码:
StreamReader reader = null;
try {
reader = File.OpenText("file.txt");
...
} finally {
if (reader != null)
((IDisposable)reader).Dispose();
}
Run Code Online (Sandbox Code Playgroud)
这将是中止安全的.
现在我的问题:
using声明是不是中止安全还是错误,它的行为与我的第二个解决方案相似?using等同于第一方案(不放弃安全的),为什么它检查null的finally?ThreadAbortException可以在托管代码中的任何位置抛出.但也许有例外,第一个变种毕竟是中止安全的?编辑:我知道使用thread.Abort()不被认为是好习惯.我的兴趣是纯粹的理论:如何在using声明中表现究竟?
c# ×8
.net ×4
abort ×1
coding-style ×1
delegates ×1
formula ×1
fusion ×1
hashcode ×1
if-statement ×1
il ×1
math ×1
this ×1
type-safety ×1
types ×1