以下结果对我没有任何意义.在执行加法或减法之前,看起来负偏移被转换为无符号.
double[] x = new double[1000];
int i = 1; // for the overflow it makes no difference if it is long, int or short
int j = -1;
unsafe
{
fixed (double* px = x)
{
double* opx = px+500; // = 0x33E64B8
//unchecked
//{
double* opx1 = opx+i; // = 0x33E64C0
double* opx2 = opx-i; // = 0x33E64B0
double* opx3 = opx+j; // = 0x33E64B0 if unchecked; throws overflow exception if checked
double* opx4 = opx-j; // = …Run Code Online (Sandbox Code Playgroud) 我试图定义一个属性,返回指向泛型类型参数的指针,如下所示:
public class MemWrapper<T> where T: struct
{
readonly IntPtr pointerToUnmanagedHeapMem;
// ... do some memory management also ...
public unsafe T* Ptr
{
get {return (T*)(pointerToUnmanagedHeapMem);}
}
}
Run Code Online (Sandbox Code Playgroud)
编译器抱怨无法声明指向托管类型T的指针或获取其地址或大小(CS0208).奇怪的是,如果我用一个具体的结构手动替换泛型类型参数,那就是
public class MyStructMemWrapper
{
readonly IntPtr pointerToUnmanagedHeapMem;
// ... do some memory management also ...
public unsafe MyStruct* Ptr
{
get {return (MyStruct*)(pointerToUnmanagedHeapMem);}
}
}
Run Code Online (Sandbox Code Playgroud)
一切都很好.但是,我必须为我使用的每个结构创建一个特殊版本的包装器.那么为什么通用甚至关心它正在铸造什么样的不安全指针呢?
背景信息:我使用的是本机dll,它反过来调用我的c#回调函数,并将其作为指针传递给我最常用的用户数据结构(更准确地说:伪装成IntPtr).为了能够传递GC稳定指针,我在非托管堆上分配我的用户数据结构.因此,我必须注意最后再次释放内存.
由于这是当然都在一个什么样的忠实C#程序员可以承受的极限,我创建一个包装类(周围堆分配和指针的使用情况,以结构)分开我尽可能多地从丑陋的东西.为了尽可能方便地为非托管堆上的结构赋值,我想定义上面的属性.
public struct MyStruct {public double x;}
// ...
MemWrapper<MyStruct> m = new MemWrapper<MyStruct>();
unsafe
{
// ideally I would like to …Run Code Online (Sandbox Code Playgroud) 我想最后用大写字母对List <string>区分大小写,即按顺序排序
一,ABC,B,BXY,C,A,AX,B,C,...
我试过了
Comparison<string> c = (string x1,string x2) => StringComparer.Ordinal.Compare(x1,x2);
list.Sort(c);
Run Code Online (Sandbox Code Playgroud)
但它回来了
A,AX,B,C,A,ABC,B,BXY,C,...
有没有任何预定义的方法来做到这一点,还是我需要自己拼凑一些东西?
编辑:由于"资本最后"似乎很难,我暂时保留了数字.
直到现在我才认为 Marshal.SizeOf 是计算非托管堆上 blittable 结构的内存大小的正确方法(这似乎是 SO 上的共识以及网络上几乎所有其他地方的共识)。
但是在阅读了一些针对 Marshal.SizeOf 的警告之后(这篇文章在“但是有一个问题......”之后)我尝试了一下,现在我完全困惑了:
public struct TestStruct
{
public char x;
public char y;
}
class Program
{
public static unsafe void Main(string[] args)
{
TestStruct s;
s.x = (char)0xABCD;
s.y = (char)0x1234;
// this results in size 4 (two Unicode characters)
Console.WriteLine(sizeof(TestStruct));
TestStruct* ps = &s;
// shows how the struct is seen from the managed side... okay!
Console.WriteLine((int)s.x);
Console.WriteLine((int)s.y);
// shows the same as before (meaning that -> is based …Run Code Online (Sandbox Code Playgroud) 我写了以下测试(实际上在更广泛的背景下使用)
IntPtr x = Marshal.AllocHGlobal(100000000);
Console.Write("Press any key to continue . . . ");
Console.ReadKey(true);
Marshal.FreeHGlobal(x);
Console.ReadKey(true);
Run Code Online (Sandbox Code Playgroud)
为什么任务管理器在第一次按键之前没有显示分配的100兆字节的任何迹象?如果这是设计的,我还能如何测试非托管堆内存的消耗?
今天我看一下Thumb控件的实现,以了解它是如何工作的.令我印象深刻的是,有3种方法似乎覆盖了内部虚拟父方法,即
internal override int EffectiveValuesInitialSize {get;}
internal override DependencyObjectType DTypeThemeStyleKey {get;}
internal override void ChangeVisualState(bool useTransitions);
Run Code Online (Sandbox Code Playgroud)
我对这些方法具体做什么并不是很感兴趣,而是允许仅在内部覆盖它们的有效理由(Microsoft).我找不到任何关于此的明显信息.
为什么要扩展Control/FrameworkElement/UIElement/etc的某些功能.普通用户无法使用?对我来说,唯一合理的解释似乎是,这个功能是针对WPF的特定子类设计的,这在某种程度上违反了OOP原则,不是吗?
我默默地认为,微软不仅可以说:"我们可以用我们的框架做一些你不能做的事,tee-hee".
跟进: Thumb中的大多数内部内容都与视觉状态有关.所以我得出结论,我可以安全地摆脱我正在创建的新类中的接口部分,并在我需要它时实现我自己的视觉状态.
我想在Modelica中执行以下操作:在特定模型中,我有几个参数h,我想通过求解参数和其他值之间的一组隐式方程,从中推导出一些与时间无关的值k.由于方程本质上是隐式的,我不能简单地指定一个表达式,我宁愿让解算器找到解决方案.
由于参数是常数,我希望能够在系统的其余部分(例如,包含k作为系数的微分方程)的实际时间积分之前,在开始时仅解决方程一次.
请参阅以下我希望能够编写的示例:
model ConstantTest
parameter Real h = 2;
const Real k;
initial equation
k*k=h; // just an example of an implicit equation, which in this simple case could also be written explicitly
end ConstantTest;
Run Code Online (Sandbox Code Playgroud)
但这失败了,因为Modelica中的"常数"不仅在消失时间导数的意义上是常数,而且在初始方程求解时它也已经是不可变的.所以求解器抱怨它无法求解初始方程0 = 2,这是因为假设k总是等于0.
当然我可以让ka变量,但是我必须明确地告诉求解器k具有消失时间导数(相当于它在天真的物理意义上实际上是"常数"):
model ConstantTest
parameter Real h = 2;
Real k;
initial equation
k*k=h;
equation
der(k) = 0;
end ConstantTest;
Run Code Online (Sandbox Code Playgroud)
这是有效的,但它有点奇怪,因为求解器必须在每个时间步骤解决一个微不足道的微分方程,以便基本上什么都不做k.这将浪费计算资源.
有没有办法用Modelica解决静态隐式方程而不引入"时间演化开销"?
我想将一个复杂模型实例化为另一个模型中的参数,并在初始方程部分中对其进行初始化,就像我可以对任何实数参数所做的那样。对于一个简单的实数参数我会写
parameter Real y(fixed = true);
Run Code Online (Sandbox Code Playgroud)
表明y应该在初始化时使用初始方程(待定义...)进行计算。但我不能对复杂的模型这样做,即
parameter ComplexModel m(fixed = true);
Run Code Online (Sandbox Code Playgroud)
不编译。例如,考虑以下平面模型
model FlatModel
parameter Real x = 4;
parameter Real y(fixed = false);
Real z;
// ... + many other model elements
initial equation
y*y = x;
// ... + many other equations
equation
z*z = 4*x;
end FlatModel;
Run Code Online (Sandbox Code Playgroud)
这里,隐式解 y=2 是在初始化时计算的,而解 z=4 是以时间相关的方式计算的(至少原则上,尽管可能进行优化......)。但两者都表示基本相同的二次关系,因此我想将这个方程封装到一个单独的模型中(请注意,并非每个这样的方程组都像本示例中那样简单):
model ComplexModel
Real x(fixed = false);
Real y(fixed = false);
equation
y * y = x;
end ComplexModel;
Run Code Online (Sandbox Code Playgroud)
并尝试这样使用它:
model RefactoredFlatModel
parameter …Run Code Online (Sandbox Code Playgroud) 令我惊讶的是,我今天发现了一个强大的功能.因为它看起来好得令人难以置信,所以我想确保它不仅仅是因为一些奇怪的巧合而起作用.
我一直认为当我的p/invoke(到c/c ++库)调用需要一个(回调)函数指针时,我必须在静态c#函数上传递一个委托.例如,在下面我将始终将KINSysFn的委托引用到该签名的静态函数.
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate int KINSysFn(IntPtr uu, IntPtr fval, IntPtr user_data );
Run Code Online (Sandbox Code Playgroud)
并使用此委托参数调用我的P/Invoke:
[DllImport("some.dll", EntryPoint = "KINInit", ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
public static extern int KINInit(IntPtr kinmem, KINSysFn func, IntPtr tmpl);
Run Code Online (Sandbox Code Playgroud)
但是现在我只是尝试并传递了一个实例方法的委托,它也起作用了!例如:
public class MySystemFunctor
{
double c = 3.0;
public int SystemFunction(IntPtr u, IntPtr v, IntPtr userData) {}
}
// ...
var myFunctor = new MySystemFunctor();
KINInit(kinmem, myFunctor.SystemFunction, IntPtr.Zero);
Run Code Online (Sandbox Code Playgroud)
当然,我理解在托管代码中,将"this"对象与实例方法一起打包以形成相应的委托,根本没有技术问题.
但让我感到惊讶的是,MySystemFunctor.SystemFunction的"this"对象也找到了本地dll的方式,它只接受静态函数,并没有为"this"对象包含任何工具或打包它与功能一起.
这是否意味着任何此类委托被单独转换(编组?)到静态函数,其中对相应"this"对象的引用在某种程度上是在函数定义中硬编码的?如何在不同的委托实例之间区分,例如,如果我有
var myFunctor01 = new MySystemFunctor();
// ...
var myFunctor99 = new MySystemFunctor();
KINInit(kinmem, …Run Code Online (Sandbox Code Playgroud) 当我使用 XmlTextReader 反序列化一个 XML 文档时,一个没有对应类的文本元素会被简单地忽略。
注意:这不是关于 XML 中缺少的元素,它需要存在,而是存在于 XML 文本中,同时在代码中没有等效的属性。
我本来希望得到一个异常,因为如果运行时数据中缺少相应的元素并且我稍后对其进行序列化,则生成的 XML 文档将与原始文档不同。所以忽略它是不安全的(在我的现实世界中,我刚刚忘记定义给定文档包含的 99 多个类之一,我一开始没有注意到)。
那么这是否正常,如果是,为什么?如果元素无法序列化,我可以以某种方式请求获得异常吗?
在下面的示例 XML 中,我故意拼错了“MyComandElement”来说明核心问题:
<MyRootElement>
<MyComandElement/>
</MyRootElement>
Run Code Online (Sandbox Code Playgroud)
MyRootElement.cs:
public class CommandElement {};
public class MyRootElement
{
public CommandElement MyCommandElement {get; set;}
}
Run Code Online (Sandbox Code Playgroud)
反序列化:
XmlSerializer xmlSerializer = new XmlSerializer(typeof(MyRootElement));
XmlTextReader xmlReader = new XmlTextReader(@"pgtest.xml");
MyRootElement mbs2 = (MyRootElement)xmlSerializer.Deserialize(xmlReader);
xmlReader.Close();
Run Code Online (Sandbox Code Playgroud) 我有一个声明虚拟方法的类。但是,此方法的特定实现未明确引用“ this”对象。他们只是返回一个特定于该类的值。
因此,人们可能一直希望不仅在特定对象上而且在类本身上都调用此方法。由于在语法层面上这当然是不可能的,所以我认为至少应该通过反思来实现。也就是说,我要遍历程序集中的所有类,并确定哪个类返回哪个值作为所述方法的响应。
但是,我的幼稚方法在尝试调用该方法时失败,并出现了空引用异常。为什么?我希望它能够成功,因为我已经使用了一个具体的类来标识具体的重写方法,因此不需要“ this”对象及其虚拟方法表来解析该方法。
我该如何运作?(当然,不包括定义第二个返回相同值的真正静态方法的“解决方案”)。
using System;
using System.Reflection;
namespace StaticInvoke
{
public abstract class Foo
{
public abstract string StaticValue {get;}
}
public class MyFirstFoo: Foo
{
public override string StaticValue {get {return "A first attempt to foo-ize Foo.";}}
}
class Program
{
public static void Main(string[] args)
{
Type myFirstFooType = typeof(MyFirstFoo);
PropertyInfo myFirstStaticValueProperty = myFirstFooType.GetProperty("StaticValue");
MethodInfo myFirstStaticValueMethod = myFirstStaticValueProperty.GetGetMethod();
string result = (string)myFirstStaticValueMethod.Invoke(null, null);
Console.WriteLine("MyFirstFoo.StaticValue == "+result);
Console.Write("Press any key to continue . . . "); …Run Code Online (Sandbox Code Playgroud)