什么';这是你遇到的最奇怪的情况;你在C#或.NET中见过吗?
我收集了一些角落里的箱子,希望能听到更多。该页面只涵盖了C#语言和BOB,但我也发现核心.NET内容也很有趣。例如,有一个页面上没有,但我觉得不可思议:什么';这是你遇到的最奇怪的情况;你在C#或.NET中见过吗?,c#,.net,C#,.net,我收集了一些角落里的箱子,希望能听到更多。该页面只涵盖了C#语言和BOB,但我也发现核心.NET内容也很有趣。例如,有一个页面上没有,但我觉得不可思议: string x = new string(new char[0]); string y = new string(new char[0]); Console.WriteLine(object.ReferenceEquals(x, y)); 我希望打印False——毕竟,“new”(带有引用类型)总是创建一个新对象,不是吗?C#和CLI的规范
string x = new string(new char[0]);
string y = new string(new char[0]);
Console.WriteLine(object.ReferenceEquals(x, y));
我希望打印False——毕竟,“new”(带有引用类型)总是创建一个新对象,不是吗?C#和CLI的规范都表明它应该。嗯,在这个特殊的情况下没有。它打印的是真的,并且在我测试过的框架的每个版本上都做过。(无可否认,我还没有在Mono上试过……)
说清楚一点,这只是我正在寻找的一个例子——我并不是特别想要讨论/解释这种奇怪的现象。(这与普通的字符串内部处理不同;特别是,调用构造函数时通常不会发生字符串内部处理。)我真的要求类似的奇怪行为
还有其他的宝藏吗?我想我以前给你看过这个,但我喜欢这里的乐趣-这需要一些调试才能找到!(原始代码显然更加复杂和微妙…) 但是它可以被打败!使用与远程处理相同的间接方式;警告-以下是纯粹的邪恶:
class MyFunnyProxyAttribute : ProxyAttribute {
public override MarshalByRefObject CreateInstance(Type serverType) {
return null;
}
}
[MyFunnyProxy]
class MyFunnyType : ContextBoundObject { }
有了这个选项,new()
调用被重定向到代理(MyFunnyProxyAttribute
),该代理返回null
。现在去洗你的眼睛
Public Class Item
Public ID As Guid
Public Text As String
Public Sub New(ByVal id As Guid, ByVal name As String)
Me.ID = id
Me.Text = name
End Sub
End Class
Public Sub Load(sender As Object, e As EventArgs) Handles Me.Load
Dim box As New ComboBox
Me.Controls.Add(box) 'Sorry I forgot this line the first time.'
Dim h As IntPtr = box.Handle 'Im not sure you need this but you might.'
Try
box.Items.Add(New Item(Guid.Empty, Nothing))
Catch ex As Exception
MsgBox(ex.ToString())
End Try
End Sub
输出为“试图读取受保护内存。这表示其他内存已损坏。”
这一个并不是一个编译器错误或故障,但肯定是一个奇怪的角落情况
Net框架采用一种称为银行家舍入的方案或舍入
在银行家的四舍五入中,0.5的数字被四舍五入到最接近的偶数,因此
Math.Round(-0.5) == 0
Math.Round(0.5) == 0
Math.Round(1.5) == 2
Math.Round(2.5) == 2
etc...
这可能会导致基于更广为人知的舍入-半向上舍入的财务计算出现一些意想不到的错误
VisualBasic也是如此。有趣的是,当我第一次看到它时,我假设它是C#编译器正在检查的东西,但即使您直接发出IL以消除任何干扰机会,它仍然会发生,这意味着执行检查的确实是
newobj
操作代码
var method = new DynamicMethod("Test", null, null);
var il = method.GetILGenerator();
il.Emit(OpCodes.Ldc_I4_0);
il.Emit(OpCodes.Newarr, typeof(char));
il.Emit(OpCodes.Newobj, typeof(string).GetConstructor(new[] { typeof(char[]) }));
il.Emit(OpCodes.Ldc_I4_0);
il.Emit(OpCodes.Newarr, typeof(char));
il.Emit(OpCodes.Newobj, typeof(string).GetConstructor(new[] { typeof(char[]) }));
il.Emit(OpCodes.Call, typeof(object).GetMethod("ReferenceEquals"));
il.Emit(OpCodes.Box, typeof(bool));
il.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", new[] { typeof(object) }));
il.Emit(OpCodes.Ret);
method.Invoke(null, null);
如果您检查
字符串,则它也等同于true
。Empty
,这意味着此操作代码必须具有特殊的行为来插入空字符串。布尔值何时既不为true也不为False?
比尔发现你可以破解一个布尔值,这样如果a为真,B为真,(a和B)为假
如果此函数被称为
Rec(0)
(不在调试器下),它将做什么
静态无效记录(int i)
{
控制台写入线(i);
if(i
答复:
- 在32位JIT上,它应该导致StackOverflowException
- 在64位JIT上,它应该将所有数字打印为int.MaxValue
object[] oArray = new string[] { "one", "two", "three" };
string[] sArray = (string[])oArray;
// Also works for IList (and IEnumerable, ICollection)
IList<string> sList = (IList<string>)oArray;
IList<object> oList = new string[] { "one", "two", "three" };
我去派对晚了一点,但我有三四五个:
enum MyEnum
{
Red,
Blue,
}
如果您在另一个程序集中计算MyEnum.Red.ToString(),并且在这段时间内有人将您的枚举重新编译为:
enum MyEnum
{
Black,
Red,
Blue,
}
在运行时,您将得到“黑色”下面是一个示例,说明如何创建导致错误消息“试图读取或写入受保护内存。这通常表示其他内存已损坏”的结构。 成功和失败之间的区别是非常微妙的 下面的单元测试演示了这个问题 看看你能不能找出哪里出了问题
[Test]
public void Test()
{
var bar = new MyClass
{
Foo = 500
};
bar.Foo += 500;
Assert.That(bar.Foo.Value.Amount, Is.EqualTo(1000));
}
private class MyClass
{
public MyStruct? Foo { get; set; }
}
private struct MyStruct
{
public decimal Amount { get; private set; }
public MyStruct(decimal amount) : this()
{
Amount = amount;
}
public static MyStruct operator +(MyStruct x, MyStruct y)
{
return new MyStruct(x.Amount + y.Amount);
}
public static MyStruct operator +(MyStruct x, decimal y)
{
return new MyStruct(x.Amount + y);
}
public static implicit operator MyStruct(int value)
{
return new MyStruct(value);
}
public static implicit operator MyStruct(decimal value)
{
return new MyStruct(value);
}
}
几年前,当我们致力于忠诚计划时,我们对给予客户的积分数量存在问题。该问题与将double转换为int有关 代码如下:
double d = 13.6;
int i1 = Convert.ToInt32(d);
int i2 = (int)d;
i1==i2吗
结果是i1!=i2。
由于Convert和cast运算符中的舍入策略不同,实际值为:
i1 == 14
i2 == 13
最好调用Math.天花()或Math.Floor()(或者使用满足我们要求的中点舍入的Math.Round)
即使存在枚举函数,它们也应该将0设置为整数
enum MyEnum
{
Black,
Red,
Blue,
}
[Test]
public void Test()
{
var bar = new MyClass
{
Foo = 500
};
bar.Foo += 500;
Assert.That(bar.Foo.Value.Amount, Is.EqualTo(1000));
}
private class MyClass
{
public MyStruct? Foo { get; set; }
}
private struct MyStruct
{
public decimal Amount { get; private set; }
public MyStruct(decimal amount) : this()
{
Amount = amount;
}
public static MyStruct operator +(MyStruct x, MyStruct y)
{
return new MyStruct(x.Amount + y.Amount);
}
public static MyStruct operator +(MyStruct x, decimal y)
{
return new MyStruct(x.Amount + y);
}
public static implicit operator MyStruct(int value)
{
return new MyStruct(value);
}
public static implicit operator MyStruct(decimal value)
{
return new MyStruct(value);
}
}
double d = 13.6;
int i1 = Convert.ToInt32(d);
int i2 = (int)d;
i1 == 14
i2 == 13
int i1 = Convert.ToInt32( Math.Ceiling(d) );
int i2 = (int) Math.Ceiling(d);
namespace Craft
{
enum Symbol { Alpha = 1, Beta = 2, Gamma = 3, Delta = 4 };
class Mate
{
static void Main(string[] args)
{
JustTest(Symbol.Alpha); // enum
JustTest(0); // why enum
JustTest((int)0); // why still enum
int i = 0;
JustTest(Convert.ToInt32(0)); // have to use Convert.ToInt32 to convince the compiler to make the call site use the object version
JustTest(i); // it's ok from down here and below
JustTest(1);
JustTest("string");
JustTest(Guid.NewGuid());
JustTest(new DataTable());
Console.ReadLine();
}
static void JustTest(Symbol a)
{
Console.WriteLine("Enum");
}
static void JustTest(object o)
{
Console.WriteLine("Object");
}
}
}
if (true)
{
OleDbCommand command = SQLServer.CreateCommand();
}
OleDbCommand command = SQLServer.CreateCommand();
interface IFoo
{
string Message {get;}
}
...
IFoo obj = new IFoo("abc");
Console.WriteLine(obj.Message);
public class Turtle<T> where T : Turtle<T>
{
}
stringvariable1.Equals(stringvariable2, StringComparison.InvariantCultureIgnoreCase);
if (assemblyfilename.EndsWith("someparticular.dll", StringComparison.InvariantCultureIgnoreCase))
{
assemblyfilename = "someparticular_modified.dll";
}
Dim i As Integer? = If(True, Nothing, 5)
enumProperty.SetValue(obj, 1, null); //works
nullableIntProperty.SetValue(obj, 1, null); //works
nullableEnumProperty.SetValue(obj, MyEnum.Foo, null); //works
nullableEnumProperty.SetValue(obj, 1, null); // throws an exception !!!
public void Foo()
{
this = new Teaser();
}
string cheat = @"
public void Foo()
{
this = new Teaser();
}
";
public struct Teaser
{
public void Foo()
{
this = new Teaser();
}
}
class Program
{
static void Main(string[] args)
{
Derived d = new Derived();
d.Property = "AWESOME";
}
}
class Base
{
string _baseProp;
public virtual string Property
{
get
{
return "BASE_" + _baseProp;
}
set
{
_baseProp = value;
//do work with the base property which might
//not be exposed to derived types
//here
Console.Out.WriteLine("_baseProp is BASE_" + value.ToString());
}
}
}
class Derived : Base
{
string _prop;
public override string Property
{
get { return _prop; }
set
{
_prop = value;
base.Property = value;
} //<- put a breakpoint here then mouse over BaseProperty,
// and then mouse over the base.Property call inside it.
}
public string BaseProperty { get { return base.Property; } private set { } }
}
((TestProject1.Base)(d))
public string BaseProperty { get { return ((TestProject1.Base)(d)).Property; } private set { } }
string filename = @"c:\program files\my folder\test.txt";
System.IO.File.WriteAllText(filename, "Hello world.");
bool exists = System.IO.File.Exists(filename); // returns true;
string text = System.IO.File.ReadAllText(filename); // Returns "Hello world."
public class DummyObject
{
public override string ToString()
{
return null;
}
}
DummyObject obj = new DummyObject();
Console.WriteLine("The text: " + obj.GetType() + " is " + obj);
object obj2 = args[i];
string text = (obj2 != null) ? obj2.ToString() : string.Empty;
// if obj2 is non-null, but obj2.ToString() returns null, then text==null
int length = text.Length;
Bool aBoolValue;
Byte aByteValue = aBoolValue ? 1 : 0;
Int anIntValue = aBoolValue ? 1 : 0;
interface I<T> {
T M(T p);
}
abstract class A<T> : I<T> {
public abstract T M(T p);
}
abstract class B<T> : A<T>, I<int> {
public override T M(T p) { return p; }
public int M(int p) { return p * 2; }
}
class C : B<int> { }
class Program {
static void Main(string[] args) {
Console.WriteLine(new C().M(42));
}
}
C:\Temp>type Program.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication1 {
interface I<T> {
T M(T p);
}
abstract class A<T> : I<T> {
public abstract T M(T p);
}
abstract class B<T> : A<T>, I<int> {
public override T M(T p) { return p; }
public int M(int p) { return p * 2; }
}
class C : B<int> { }
class Program {
static void Main(string[] args) {
Console.WriteLine(new C().M(11));
}
}
}
C:\Temp>csc Program.cs
Microsoft (R) Visual C# 2008 Compiler version 3.5.30729.1
for Microsoft (R) .NET Framework version 3.5
Copyright (C) Microsoft Corporation. All rights reserved.
C:\Temp>Program
Unhandled Exception: System.TypeLoadException: Could not load type 'ConsoleAppli
cation1.C' from assembly 'Program, Version=0.0.0.0, Culture=neutral, PublicKeyTo
ken=null'.
at ConsoleApplication1.Program.Main(String[] args)
C:\Temp>peverify Program.exe
Microsoft (R) .NET Framework PE Verifier. Version 3.5.30729.1
Copyright (c) Microsoft Corporation. All rights reserved.
[token 0x02000005] Type load failed.
[IL]: Error: [C:\Temp\Program.exe : ConsoleApplication1.Program::Main][offset 0x
00000001] Unable to resolve token.
2 Error(s) Verifying Program.exe
C:\Temp>ver
Microsoft Windows XP [Version 5.1.2600]
class TwoWayRelationship<T1, T2>
{
public T2 Get(T1 key) { /* ... */ }
public T1 Get(T2 key) { /* ... */ }
}
var r1 = new TwoWayRelationship<int, string>();
r1.Get(1);
r1.Get("a");
var r2 = new TwoWayRelationship<int, int>();
r2.Get(1); // "The call is ambiguous..."
return test != null ? test : GetDefault();
if (test == null)
return GetDefault();
return test;
return test ?? GetDefault();
public class Derived : Base
{
public int BrokenAccess()
{
return base.m_basePrivateField;
}
}
private int m_basePrivateField = 0;
public class Base
{
private int m_basePrivateField = 0;
public class Derived : Base
{
public int BrokenAccess()
{
return base.m_basePrivateField;
}
}
}
public interface MyInterface {
void Method();
}
public class Base {
public void Method() { }
}
public class Derived : Base, MyInterface { }
public class Base
{
public virtual void Initialize(dynamic stuff) {
//...
}
}
public class Derived:Base
{
public override void Initialize(dynamic stuff) {
base.Initialize(stuff);
//...
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Remoting.Proxies;
using System.Reflection;
using System.Runtime.Remoting.Messaging;
namespace BrokenProxy
{
class NotAnIAsyncResult
{
public string SomeProperty { get; set; }
}
class BrokenProxy : RealProxy
{
private void HackFlags()
{
var flagsField = typeof(RealProxy).GetField("_flags", BindingFlags.NonPublic | BindingFlags.Instance);
int val = (int)flagsField.GetValue(this);
val |= 1; // 1 = RemotingProxy, check out System.Runtime.Remoting.Proxies.RealProxyFlags
flagsField.SetValue(this, val);
}
public BrokenProxy(Type t)
: base(t)
{
HackFlags();
}
public override IMessage Invoke(IMessage msg)
{
var naiar = new NotAnIAsyncResult();
naiar.SomeProperty = "o noes";
return new ReturnMessage(naiar, null, 0, null, (IMethodCallMessage)msg);
}
}
interface IRandomInterface
{
int DoSomething();
}
class Program
{
static void Main(string[] args)
{
BrokenProxy bp = new BrokenProxy(typeof(IRandomInterface));
var instance = (IRandomInterface)bp.GetTransparentProxy();
Func<int> doSomethingDelegate = instance.DoSomething;
IAsyncResult notAnIAsyncResult = doSomethingDelegate.BeginInvoke(null, null);
var interfaces = notAnIAsyncResult.GetType().GetInterfaces();
Console.WriteLine(!interfaces.Any() ? "No interfaces on notAnIAsyncResult" : "Interfaces");
Console.WriteLine(notAnIAsyncResult is IAsyncResult); // Should be false, is it?!
Console.WriteLine(((NotAnIAsyncResult)notAnIAsyncResult).SomeProperty);
Console.WriteLine(((IAsyncResult)notAnIAsyncResult).IsCompleted); // No way this works.
}
}
}
No interfaces on notAnIAsyncResult
True
o noes
Unhandled Exception: System.EntryPointNotFoundException: Entry point was not found.
at System.IAsyncResult.get_IsCompleted()
at BrokenProxy.Program.Main(String[] args)