遍布Stack Overflow和互联网我发现保持结构不可变是一个很好的设计原则.不幸的是,我从来没有看到任何实际上导致这些结构真正不可变的实现.
假设一个struct里面没有任何引用类型,我如何实际构造一个struct不可变?也就是说,如何防止任何原始字段的变异(可能是编译时/运行时异常)?
我写了一个简单的测试,尝试使一个结构不可变,但甚至没有使用System.ComponentModel.ImmutableObjectAttribute
工作:
class Program
{
static void Main(string[] args)
{
ImmutableStruct immStruct1 = new ImmutableStruct();
Console.WriteLine(immStruct1); //Before mutation.
immStruct1.field1 = 1;
immStruct1.field2 = "Hello";
immStruct1.field3 = new object();
Console.WriteLine(immStruct1); //After 1st mutation.
immStruct1.field1 = 2;
immStruct1.field2 = "World";
immStruct1.field3 = new object();
Console.WriteLine(immStruct1); //After 2nd mutation.
Console.ReadKey();
}
}
[ImmutableObject(true)]
struct ImmutableStruct
{
public int field1;
public string field2;
public object field3;
public override string ToString()
{
string field3String = "null";
if (field3 != null)
{ …
Run Code Online (Sandbox Code Playgroud) 在Windows API中,我正在研究GetMessage
函数的实际工作方式.我已经看到了3个Windows消息循环的实现,并希望探索它们.
截至撰写本文时,这篇MSDN文章描述了我认为实现消息循环的正确方法.
MSG msg;
BOOL bRet;
while( (bRet = GetMessage( &msg, NULL, 0, 0 )) != 0)
{
if (bRet == -1)
{
// handle the error and possibly exit
}
else
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
Run Code Online (Sandbox Code Playgroud)
在GetMessage
功能页面上,我看到了这个实现:
MSG msg;
BOOL bRet;
while( (bRet = GetMessage( &msg, hWnd, 0, 0 )) != 0)
{
if (bRet == -1)
{
// handle the error and possibly exit
}
else …
Run Code Online (Sandbox Code Playgroud) 这个问题是对这个问题的跟进:
这个问题非常适合理解为什么使用char []而不是String; 但是,它没有解释如何以安全的方式对char []执行密码验证.这就是我想知道的.
简而言之,我需要检查密码是否符合以下要求:
现在我明白了如何使用正则表达式来执行验证......这些答案显示了如何做到这一点:
据我所知,正则表达式检查涉及使用字符串.使用它们似乎不安全,因为字符串是不可变的,因此在使用它们后不能立即清除它们.另一方面,char []可以被清除.
我可以遍历每个角色,但是我必须创建我想要测试的每个集合.理想情况下,能够利用正则表达式会很有用.
在Java中,我可以通过以下方法进行正则表达式检查.
String.matches(String regex)
Run Code Online (Sandbox Code Playgroud)
要么
Pattern pattern = Pattern.compile(String regex);
pattern.matcher(CharSequence testString).matches();
Run Code Online (Sandbox Code Playgroud)
如您所见,这两种方法都不支持直接使用char [].
我有一个可重复使用的对话框/窗口,提示用户从列表框中选择一个项目,单击"确定"以确认选择.
它很棒; 但是,列表框不知道它提前处理的数据类型.因此,列表绑定到ObservableCollection<Object>
可由对话框的调用者设置的列表.
此外,列表框还有一个自定义项模板,允许用户从列表中删除项.
这是我正在描述的对话框:
理想情况下,我想利用DisplayMemberPath
列表框,但我不允许,因为我正在创建自己的项目模板.这是一个问题,因为调用者应该能够指定他/她想要绑定到我设置的自定义项模板的属性.
由于这种方法不起作用,我的第一个问题是:
在XAML中,我希望看到类似的东西,但这是错误的:
<ListBox.ItemTemplate>
<Label Content="{Binding Path={Binding CustomPath}}"/>
<Button Width="20" Height="20" FontWeight="Bold" Content="×"/>
</ListBox.ItemTemplate>
Run Code Online (Sandbox Code Playgroud)
(为简洁起见省略了一些属性)
假设第一个问题已经解决,我还有另外一个问题.列表框使用的是非泛型类型Object
,它不具有调用者想要绑定的属性.列表框无法将对象强制转换为自定义类型并访问所需的属性.这引出了我的第二个问题.
也许这应留给SO上的另一个问题,但是能够指定绑定是否使用ToString()
或属性是很好的.
我能想到的唯一解决方案是创建一个具有DisplayText
调用者必须使用的属性(命名)的接口.然后该列表将绑定到的实例ObservableCollection<CustomInterface>
.
但是,不希望将现有的数据类型包装到此接口中,因此这样可行.有一个更好的方法吗?
编辑:实现者如何使用ListDialogBox
以下是我希望调用者能够设置对话框(或类似简单的东西):
public CustomItem PromptForSelection()
{
ListDialogBox dialog = new ListDialogBox();
dialog.Items = GetObservableCollection();
dialog.ListDisplayMemberPath = "DisplayName";
dialog.ShowDialog();
if(!dialog.IsCancelled)
{
return (CustomItem) dialog.SelectedItem;
}
}
public ObservableCollection<Object> GetObservableCollection()
{
ObservableCollection<Object> coll = new ObservableCollection<Object>();
CustomItem item = new CustomItem();
item.DisplayName = …
Run Code Online (Sandbox Code Playgroud) 我知道这CoerceValueCallback
用于纠正一个值,ValidateValueCallback
并返回true或false.但我的问题是我们为什么需要ValidatevalueCallback
?我们可以简单地使用CoerceValueCallback
来验证(使用if条件)并更正值.你能举出一些关于何时使用强制与验证的实际例子吗?
我将为高分辨率波形处理大约320,000,000个数据点。每个数据点需要2个浮点数(XY坐标),总共8个字节。
为了一次性分配所有内存,我计划使用struct
以下代码:
public struct Point
{
public float X; //4-bytes
public float Y; //4-bytes.
}
Run Code Online (Sandbox Code Playgroud)
由于struct是一种值类型,因此我假设它仅消耗每个变量所需的内存量,以及CLR(公共语言运行时)使用的少量固定内存。
有没有一种方法可以计算结构在应用程序运行期间将使用多少内存?也就是说,我知道以下内容:
我是 WPF 新手。和其他许多人一样,我试图将 a 绑定ContextMenu
到 anObservableCollection
以创建动态上下文菜单。Command
除了将属性绑定到代表菜单项的类TheCommand
的属性之外,一切正常。MenuItemViewModel
该命令不会被触发。我究竟做错了什么?
从头开始,ContextMenu
是 的子级Image
,当鼠标悬停在 上时会显示Image
。
<Image.ContextMenu >
<ContextMenu ItemsSource="{DynamicResource ContextMenu}"
Run Code Online (Sandbox Code Playgroud)
其中空的 ContextMenu 定义如下:
<Window.Resources>
<local:MenuItemViewModelCollection x:Key="ContextMenu">
</local:MenuItemViewModelCollection>
<HierarchicalDataTemplate DataType="{x:Type local:MenuItemViewModel}"
ItemsSource="{Binding Path=Children}">
<HierarchicalDataTemplate.ItemContainerStyle>
<Style TargetType="MenuItem">
<Setter Property="Command"
Value="{Binding RelativeSource={RelativeSource AncestorType={x:Type ContextMenu}},
Path=DataContext.TheCommand}"/>
<!-- Value="{Binding Path=TheCommand}" /> I tried this too -->
</Style>
</HierarchicalDataTemplate.ItemContainerStyle>
</HierarchicalDataTemplate>
</Window.Resources>
Run Code Online (Sandbox Code Playgroud)
该TheCommand
属性定义如下:
<Image.ContextMenu >
<ContextMenu ItemsSource="{DynamicResource ContextMenu}"
Run Code Online (Sandbox Code Playgroud) 在WinAPI中,您可以通过FindResource
和访问资源LoadResource
。
根据的文档FindResource
,您可以指定资源的名称:
lpName [输入]
类型:LPCTSTR
资源的名称。或者,该参数可以是 MAKEINTRESOURCE(ID),而不是指针,其中 ID 是资源的整数标识符。有关详细信息,请参阅下面的备注部分。
我有两个问题:
首先,这似乎并不准确,因为指定 ID 或文件名都不起作用。为参数输入的正确值是多少lpName
?
这另一个问题似乎也有这个问题
其次,我想知道是否可以在运行时检索资源的文件名。这可能吗?或者文件打包成资源后文件名就被丢弃了?
#include <Windows.h>
#include <tchar.h>
#include "resource.h"
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
//This is the only test that succeeds.
if (!FindResource(hInstance, MAKEINTRESOURCE(IDR_DRAWING1), _T("BINARY")))
{
MessageBox(NULL, _T("MAKEINTRESOURCE(IDR_DRAWING1); BINARY"), _T(""), MB_ICONERROR);
}
//This one fails.
if (!FindResource(hInstance, _T("IDR_DRAWING1"), _T("BINARY")))
{
MessageBox(NULL, _T("\"IDR_DRAWING1\"; BINARY"), _T(""), MB_ICONERROR);
}
//ICON - Each fails.
if (!FindResource(hInstance, …
Run Code Online (Sandbox Code Playgroud) 我试图将System.Windows.Shapes.Shape对象转换为System.Windows.Media.Geometry对象.
使用该Geometry
对象,我将根据一组数据点使用自定义图形控件多次渲染它.这要求Geometry
对象的每个实例都有一个唯一的TranslateTransform
对象.
现在,我正以两种不同的方式处理这个问题,但似乎都没有正常工作.我的自定义控件使用以下代码来绘制几何:
//Create an instance of the geometry the shape uses.
Geometry geo = DataPointShape.RenderedGeometry.Clone();
//Apply transformation.
TranslateTransform translation = new TranslateTransform(dataPoint.X, dataPoint.Y);
geo.Transform = translation;
//Create pen and draw geometry.
Pen shapePen = new Pen(DataPointShape.Stroke, DataPointShape.StrokeThickness);
dc.DrawGeometry(DataPointShape.Fill, shapePen, geo);
Run Code Online (Sandbox Code Playgroud)
我还尝试了以下替代代码:
//Create an instance of the geometry the shape uses.
Geometry geo = DataPointShape.RenderedGeometry;
//Apply transformation.
TranslateTransform translation = new TranslateTransform(dataPoint.X, dataPoint.Y);
dc.PushTransform(translation);
//Create pen and draw geometry.
Pen …
Run Code Online (Sandbox Code Playgroud) 我试图找到将数字 (0..9) 转换为 Kotlin 中相应字符 '0'..'9' 的最简单方法。
我最初的尝试是编写以下代码:
fun convertToCharacter() {
val number = 0
val character = number.toChar()
println(character)
}
Run Code Online (Sandbox Code Playgroud)
当然,运行后,我很快发现这会产生 \u0000,而不是我预期的“0”。然后,记住如何在 Java 中执行此操作,我修改了代码以添加“0”,但这样就无法编译。
fun convertToCharacter() {
val number = 0
val character = number.toChar() + '0'
println(character)
}
Run Code Online (Sandbox Code Playgroud)
在 Kotlin 中将数字转换为其相应字符的正确方法是什么?理想情况下,我试图避免拉出 ASCII 表来完成此操作(我知道我可以将 48 添加到数字中,因为 ASCII 中的 48 -> '0')。
c# ×4
wpf ×4
c++ ×2
struct ×2
winapi ×2
arrays ×1
command ×1
contextmenu ×1
generics ×1
geometry ×1
immutability ×1
java ×1
kotlin ×1
memory ×1
mvvm ×1
passwords ×1
regex ×1
shape ×1
silverlight ×1
validation ×1
windows ×1
wpf-controls ×1