小编Kja*_*ara的帖子

为什么不能修剪数组?

在MSDN文档站点上,它说明了以下有关该Array.Resize方法的信息:

如果newSize大于旧数组的Length,则分配一个新数组,并将所有元素从旧数组复制到新数组.

如果newSize小于旧数组的长度,则分配一个新数组,并将元素从旧数组复制到新数组,直到填充新数组为止.旧数组中的其余元素将被忽略.

数组是一系列相邻的存储块.如果我们需要一个更大的阵列,我理解我们不能为它添加内存,因为它旁边的内存可能已经被其他一些数据声明了.所以我们必须要求一个具有所需更大尺寸的新的相邻内存块序列,复制我们的条目并删除我们对旧空间的主张.

但为什么要创建一个更小尺寸的新阵列?为什么数组不仅可以删除它对最后一个内存块的声明?然后它将是O(1)操作而不是O(n),就像现在一样.

它是否与数据在计算机体系结构或物理层面的组织方式有关?

c# arrays memory-management

70
推荐指数
6
解决办法
5008
查看次数

值等于和循环引用:如何解决无限递归?

我有一些包含几个字段的类.我需要按值比较它们,即如果它们的字段包含相同的数据,则类的两个实例是相等的.我已经覆盖了GetHashCode它的Equals方法.

可能会发生这些类包含循环引用.

示例:我们想要建立机构(如政府,体育俱乐部等).一个机构有一个名字.A Club是具有名称和成员列表的机构.每个成员Person都有一个名字和最喜欢的机构.如果某个俱乐部的成员将该俱乐部作为他最喜欢的机构,我们有一个循环参考.

但循环引用与值相等一起导致无限递归.这是一个代码示例:

interface IInstitution { string Name { get; } }

class Club : IInstitution
{
    public string Name { get; set; }
    public HashSet<Person> Members { get; set; }

    public override int GetHashCode() { return Name.GetHashCode() + Members.Count; }

    public override bool Equals(object obj)
    {
        Club other = obj as Club;
        if (other == null)
            return false;

        return Name.Equals(other.Name) && Members.SetEquals(other.Members);
    }
}

class Person
{
    public string …
Run Code Online (Sandbox Code Playgroud)

c# recursion equality infinite

7
推荐指数
1
解决办法
429
查看次数

$(TargetDir) 替换 SDK 样式项目(类似于“$(MSBuildProjectDirectory)\”代表“$(ProjectDir)”)

我有一个由 Visual Studio 生成的非 SDK 样式格式的旧项目。它包含一个使用$(ProjectDir)和 的构建后事件。$(TargetDir)

我目前正在将该项目转换为一个新的SDK风格的项目(csproj文件)。如果我只是将该构建后事件转换为Target Exec Command,我会收到错误。在命令前面加上前缀后,echo我可以明白为什么:值$(ProjectDir)$(TargetDir)都是空的。

我发现替换$(ProjectDir)$(MSBuildProjectDirectory)\可以得到所需的结果,但是 的等效项是什么$(TargetDir)


请注意,我没有将 Visual Studio 用于新的 SDK 样式项目。我正在使用 Visual Studio 代码。看起来 Visual Studio 为$(ProjectDir)/ $(TargetDir)/others 设置了值,但 Visual Studio Code 没有。我使用 构建我的项目dotnet build

.net c# msbuild build csproj

7
推荐指数
1
解决办法
3903
查看次数

不使用 GetHashCode 的 HashSet 和 Dictionary 的 C# 高性能替代方案

我正在寻找比列表具有更好性能但不使用内部方法的HashSetDictionary对象的内置替代方案GetHashCode。我需要这个,因为我写的类,没有写的方式GetHashCode与满足通常的合同法Equals比其他

public override int GetHashCode() { return 0; } // or return any other constant value
Run Code Online (Sandbox Code Playgroud)

这将打开HashSet,并Dictionary分为普通列表(性能明智)。

所以我需要的是一个集合实现和一个映射实现。有什么建议?

编辑:

我的类是基于容差的 3 维向量类:

public class Vector
{
    private static const double TOL = 1E-10;
    private double x, y, z;

    public Vector(double x, double y, double z)
    {
        this.x = x; this.y = y; this.z = z;
    }

    public override bool Equals(object o)
    {
        Vector other = o …
Run Code Online (Sandbox Code Playgroud)

c# mapping set gethashcode

5
推荐指数
1
解决办法
935
查看次数

禁用TreeView中某些条目的可聚焦性

我有一个TreeView,里面装满了不同类型的项目。这些项目可以是类型Node(当时他们可能有孩子)或类型Entry(当时他们没有孩子)。为此,我将TreeView绑定到ViewModel属性AllNodesAndEntries,该属性是一个ObservableCollection<object>。对于不同的长相NodeEntry我定义了两个的DataTemplates。这是代码:

<TreeView ItemsSource="{Binding AllNodesAndEntries}">
    <TreeView.Resources>
        <HierarchicalDataTemplate ItemsSource="{Binding Children}"
                                  DataType="{x:Type local:Node}">
            <TextBlock Text="{Binding Name}"
                       Background="LightBlue"/>
        </HierarchicalDataTemplate>
        <DataTemplate DataType="{x:Type local:Entry}">
            <TextBlock Text="{Binding Name}"
                       Background="LightSalmon"/>
        </DataTemplate>
    </TreeView.Resources>
</TreeView>
Run Code Online (Sandbox Code Playgroud)

现在,如果要Entry满足特定条件(即,如果我的ViewModel属性MyProptrue),我想使元素无法定位。

因此,我将触发器添加到DataTemplate中,Entry如下所示:

        <DataTemplate DataType="{x:Type local:Entry}">
            <TextBlock Text="{Binding Name}"
                       Background="LightSalmon"/>
            <DataTemplate.Triggers>
                <DataTrigger Binding="{Binding MyProp}" Value="True">
                    <Setter Property="Focusable" Value="False"/>
                </DataTrigger>
            </DataTemplate.Triggers>
        </DataTemplate>
Run Code Online (Sandbox Code Playgroud)

但这是行不通的,MyProp设置为后,我仍然可以选择条目true我究竟做错了什么?我该如何运作?

我确实NotifyPropertyChanged(nameof(MyProp));在中设置了MyProp,所以对的更改MyProp将报告给View。

c# wpf treeview triggers

5
推荐指数
1
解决办法
188
查看次数

了解Parallel.Invoke,创建和重用线程

我试图了解如何Parallel.Invoke创建和重用线程。我运行了以下示例代码(来自MSDN,https://msdn.microsoft.com/zh-cn/library/dd642243(v = vs.110.aspx):

using System;
using System.Threading;
using System.Threading.Tasks;

class ThreadLocalDemo
{
        static void Main()
        {
            // Thread-Local variable that yields a name for a thread
            ThreadLocal<string> ThreadName = new ThreadLocal<string>(() =>
            {
                return "Thread" + Thread.CurrentThread.ManagedThreadId;
            });

            // Action that prints out ThreadName for the current thread
            Action action = () =>
            {
                // If ThreadName.IsValueCreated is true, it means that we are not the
                // first action to run on …
Run Code Online (Sandbox Code Playgroud)

c# multithreading

5
推荐指数
1
解决办法
968
查看次数

键值取决于值的键值对的集合

我上课了 MyClass

class MyClass
{
    public string Name { get; set; } // is unique among all instances
    public SomeClass Data { get; set; }
    ...
}
Run Code Online (Sandbox Code Playgroud)

其中我想在集合中存储多个实例.我经常需要检查是否存在具有特定名称的实例,如果存在,则检索该实例.由于迭代整个集合不是一个选项(性能!),我想到了一个使用键值对的集合,例如IDictionary<string, MyClass>.

我的程序还允许重命名实例MyClass(如果违反名称唯一性,则不允许重命名).但是如果我重命名一个MyClass,我还需要从字典中删除旧条目并添加新条目(即使用新名称)以保持数据一致.

问题是我将MyClass在整个地方有几个这样的字典(其中包含所有实例的子集),并且很难跟踪它们并在每次重命名后不断更新所有字典.

有没有办法让键值对自动保持一致?我想我听说过一个允许这个的数据结构,它至少存在于C++中(遗憾的是,我不知道它是如何调用的).基本上,它应该是一个集合,其中键不仅仅是一个普通字符串,而更像是对字符串的引用(在本例中为name属性),但行为就好像它是一个字符串.C#中是否存在这样的事情?您是否有其他想法如何保持收藏一致?

我唯一的想法是在我的程序的最高级别上拥有所有词典的集合,并使重命名方法在实际重命名过程之后更新所有这些词典.但必须有更好的方法!


为什么这个问题不是改变字典键最佳方法的重复:

我已经知道字典不允许更改密钥.我反而要求另一个与键更改兼容的数据结构(不会完全失去性能优势),我也要求其他方法.因此,只要有助于解决保持数据一致性的问题,我的问题就更容易从任何方向输入.

c# dictionary key-value

5
推荐指数
1
解决办法
98
查看次数

使用触发器作为资源

我想将触发器定义为资源,以便稍后在我的控件中使用它们。

像这样:

<Window.Resources>
    <DataTrigger x:Key="Trigger1" Binding="{Binding ViewModelProperty1}" Value="Val1">
        <Setter Property="IsEnabled" Value="False"/>
    </DataTrigger>
    <DataTrigger x:Key="Trigger2" Binding="{Binding ViewModelProperty2}" Value="Val2">
        <Setter Property="IsEnabled" Value="False"/>
    </DataTrigger>
    ...
</Window.Resources>
Run Code Online (Sandbox Code Playgroud)

但是,当我尝试运行代码时,编译器抱怨 IsEnabled 不是有效成员。我认为这是因为它无法知道所讨论的控件是否具有“IsEnabled”属性。与样式一样,我认为我需要以某种方式指定 TargetType(在我的情况下是FrameworkElement)。但是如何?

笔记:

请不要建议使用样式而不是触发器作为资源。由于控件只能有一种样式,但我需要为一个控件提供多个触发器,因此此处没有样式选项:

在我的实际代码中,我有一个应该有触发器 1、2 和 4 的按钮和一个应该有触发器 1 和 3 的文本框和一个应该有触发器 2、3 和 4 的标签......我想你明白了。

c# wpf resources triggers

4
推荐指数
1
解决办法
734
查看次数

实现自己的ObservableCollection

对于我的WPF项目,我需要一个可观察的集合,该集合始终保持正确的顺序。我的想法是使用SortedSet<T>和实现我自己的AddAndNotifyRemoveAndNotify方法。在其中,我会这样叫NotifyPropertyChanged

public class ObservableSortedSet<T> : SortedSet<T>, INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    public void NotifyPropertyChanged(string propName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propName));
    }

    public void AddAndNotify(T element)
    {
        Add(element);
        NotifyPropertyChanged(...);
    }

    public void RemoveAndNotify(T element)
    {
        Remove(element);
        NotifyPropertyChanged(...);
    }
}
Run Code Online (Sandbox Code Playgroud)

但是那将是哪个属性?

如果集合内容发生更改,如何实现一个告诉UI进行更新的集合?

还是通过直接在ViewModel中使用SortedSet来获得更简单的方法?

编辑:

我不想将预定义ObservableCollection与排序视图一起使用。我知道可以通过使用CollectionViewSource或转换器来实现,但是这些解决方案对我而言并不有吸引力。我有CollectionViewSource无法使用的层次结构数据,并且我认为转换器版本对于的限制是一种可怕的解决方法CollectionViewSource。我想使用干净的解决方案。

因此,此问题不是如何对ObservableCollection进行排序的重复。我不想对进行排序ObservableCollection,而是想使用SortedSet可以告知用户界面更改的。

c# wpf observablecollection

3
推荐指数
1
解决办法
1301
查看次数

将数组对转换为对数组(如果可能,使用 LINQ)

我有一些类型ST(例如S=objectT=string)。我有一对这些类型的数组,即

(S[], T[]) pairOfArrays;
Run Code Online (Sandbox Code Playgroud)

我想将其转换为成对的数组,即

(S, T)[] arrayOfPairs;
Run Code Online (Sandbox Code Playgroud)

我怎么做?如果可能的话,我对 LINQ 解决方案最感兴趣。请假设 中的两个数组pairOfArrays具有相同的长度。


我知道另一个方向:

pairOfArrays = (arrayOfPairs.Select(i => i.Item1).ToArray(),
                arrayOfPairs.Select(i => i.Item2).ToArray());
Run Code Online (Sandbox Code Playgroud)

我所寻求的方向的问题是:为了迭代(使用Select等)我需要一个IEnumerable,但(S[], T[])不是IEnumerable。如果我从 开始,那么我不知道如何获取与当前语句中pairOfArrays.Item1.Select(...相同的条目(按索引)。Item2Select

c# linq arrays ienumerable valuetuple

3
推荐指数
1
解决办法
691
查看次数