我有2 IList<T>个相同类型的对象ItemsDTO.我想从另一个列表中排除一个列表.然而,这对我来说似乎没有用,我想知道为什么?
IList<ItemsDTO> related = itemsbl.GetRelatedItems();
IList<ItemsDTO> relating = itemsbl.GetRelatingItems().Except(related).ToList();
Run Code Online (Sandbox Code Playgroud)
我正在尝试related从relating列表中删除项目.
本文的底部描述了如何使用GetOrAdd(如果我理解正确)可能导致损坏/意外结果.
喀嚓/
ConcurrentDictionary专为多线程场景而设计.您不必在代码中使用锁来添加或删除集合中的项.但是,一个线程始终可以检索一个值,而另一个线程可以通过为相同的键提供一个新值来立即更新该集合.
此外,尽管ConcurrentDictionary的所有方法都是线程安全的,但并非所有方法都是原子方法,特别是GetOrAdd和AddOrUpdate.传递给这些方法的用户委托是在字典的内部锁之外调用的.(这样做是为了防止未知代码阻塞所有线程.)因此,可能会发生以下事件序列:
1)threadA调用GetOrAdd,找不到任何项,并通过调用valueFactory委托创建一个新项添加到Add.
2)threadB同时调用GetOrAdd,调用其valueFactory委托,并在threadA之前到达内部锁,因此将其新的键值对添加到字典中.
3)threadA的用户委托完成,线程到达锁,但现在看到该项已经存在
4)threadA执行"Get",并返回先前由threadB添加的数据.
因此,无法保证GetOrAdd返回的数据与线程的valueFactory创建的数据相同.调用AddOrUpdate时,可能会发生类似的事件序列.
题
验证数据的正确方法是什么,并重试更新?一个很好的方法是根据旧值的内容尝试/重试此操作的扩展方法.
这将如何实施?我可以依赖result(verify)作为有效结束状态,还是必须使用不同的方法重试并重新检索值?
码
更新值时,以下代码具有竞争条件.期望的行为是AddOrUpdateWithoutRetrieving()将以不同的方式递增各种值(使用++或Interlocked.Increment()).
我还想在一个单元中执行多个字段操作,如果先前的更新由于竞争条件而没有"占用",则重试更新.
运行代码,您将看到控制台中出现的每个值开始增加1,但每个值都会漂移,有些值会前后几次迭代.
namespace DictionaryHowTo
{
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
// The type of the Value to store in the dictionary:
class FilterConcurrentDuplicate
{
// Create a new concurrent dictionary.
readonly ConcurrentDictionary<int, TestData> eventLogCache =
new ConcurrentDictionary<int, TestData>();
static void Main()
{
FilterConcurrentDuplicate c = new FilterConcurrentDuplicate();
c.DoRace(null);
}
readonly …Run Code Online (Sandbox Code Playgroud) c# concurrency multithreading thread-safety task-parallel-library
这是一个学术观点,但我觉得如果我不理解为什么这会被诸如Effective Java和许多SO问题这样的书推荐,我不完全理解哈希码.
假设:
public sealed class Point
{
private readonly int x;
private readonly int y;
//constructor ommited
//equals ommited
public override int GetHashcode()
{
int hash = 17; //why should the initial value be non-zero?
unchecked
{
hash = hash * 31 + x; //do not tell me why I should use primes - that is not the question
hash = hash * 31 + y;
return hash;
}
}
}
Run Code Online (Sandbox Code Playgroud)
现在,据推测,初始值的原因是它减少了其中一个组件为零的冲突.
我很想找到任何有帮助的例子.
这是一个碰撞的例子,但是初始值没有任何可能性.
x y Hash Without initial …Run Code Online (Sandbox Code Playgroud) 可以在类中使用GUID私有属性,以便在GetHashCode覆盖中使用它吗?
就像是:
public class Voucher : IComparable<Voucher>, IComparable, IEquatable<Voucher>
{
private Guid? _guid;
private Guid Guid
{
get
{
return _guid ?? (_guid = Guid.NewGuid()).GetValueOrDefault();
}
}
public int Id { get; private set; }
public string Number { get; private set; }
public DateTime Date { get; private set; }
public Voucher(string number, DateTime date)
{
Number = number;
Date = date;
}
public Voucher(int id, string number, DateTime date)
: this(number, date)
{
Id = id;
}
public …Run Code Online (Sandbox Code Playgroud) 好的,所以如果我重写Equals,我需要覆盖GetHashCode,反之亦然.
但我只是想知道:我是否应该总是在任何课程中覆盖这两个?特别是如果我知道我会在字典或类似的集合中使用它们?虽然这是相当直接的,但它仍然是每个班级的额外工作.
System.Object实现是否足以让人担心?
编辑:你能详细说明什么是价值和参考平等?因此,如果我有两个字符串(s1和s2)都是"test",它们的值相等,但由于它们是两个不同的字符串,它们不是引用相等的?好吧,对于字符串来说,这是一个明智的选择,但是你想要参考或价值平等的常见情况是什么?
String.GetHashCode的行为取决于程序架构.因此它将在x86中返回一个值,在x64上返回一个值.我有一个必须在x86中运行的测试应用程序,它必须预测必须在x64上运行的应用程序的哈希码输出.
下面是mscorwks中String.GetHashCode实现的反汇编.
public override unsafe int GetHashCode()
{
fixed (char* text1 = ((char*) this))
{
char* chPtr1 = text1;
int num1 = 0x15051505;
int num2 = num1;
int* numPtr1 = (int*) chPtr1;
for (int num3 = this.Length; num3 > 0; num3 -= 4)
{
num1 = (((num1 << 5) + num1) + (num1 >? 0x1b)) ^ numPtr1[0];
if (num3 <= 2)
{
break;
}
num2 = (((num2 << 5) + num2) + (num2 >> 0x1b)) ^ numPtr1[1];
numPtr1 += 2; …Run Code Online (Sandbox Code Playgroud) 我有一些类,如下所示,我已经实现了Equals(Object)几乎所有的方法.但我不知道怎么写 GetHashCode().到目前为止,我在Dictionary集合中使用这些数据类型作为值类型,我想我应该覆盖GetHashCode().
我不知道如何GetHashCode()用逻辑来实现Equals(Object).
2.有一些派生类,如果我覆盖GetHashCode()并且Equals(Object)对于基类(Param),是否仍然需要为子节点覆盖它?
class Param
{
...
public Int16 id { get; set; }
public String name { get; set; }
...
public override bool Equals(object obj)
{
if ( obj is Param){
Param p = (Param)(obj);
if (id > 0 && p.id > 0)
return (id == p.id);
else if (name != String.Empty && p.name != String.Empty)
return (name.equals(p.name));
else
return …Run Code Online (Sandbox Code Playgroud) 我正在从另一个数据库导入数据。
我的过程是将数据从远程数据库导入到List<DataModel>命名的数据库中,并将remoteData数据从本地数据库导入到List<DataModel>命名的localData.
然后我使用 LINQ 创建一个不同的记录列表,以便我可以更新本地数据库以匹配从远程数据库中提取的数据。像这样:
var outdatedData = this.localData.Intersect(this.remoteData, new OutdatedDataComparer()).ToList();
Run Code Online (Sandbox Code Playgroud)
然后我使用 LINQ 创建一个不再存在于remoteData中但确实存在于中的记录列表localData,以便我将它们从本地数据库中删除。
像这样:
var oldData = this.localData.Except(this.remoteData, new MatchingDataComparer()).ToList();
Run Code Online (Sandbox Code Playgroud)
然后我使用 LINQ 执行与上述相反的操作,将新数据添加到本地数据库。
像这样:
var newData = this.remoteData.Except(this.localData, new MatchingDataComparer()).ToList();
Run Code Online (Sandbox Code Playgroud)
每个集合导入大约 70k 条记录,3 个 LINQ 操作中的每一个都需要 5 到 10 分钟才能完成。我怎样才能更快?
这是集合正在使用的对象:
internal class DataModel
{
public string Key1{ get; set; }
public string Key2{ get; set; }
public string Value1{ get; set; }
public string Value2{ …Run Code Online (Sandbox Code Playgroud) 我有一个类,它具有许多我正在实现的属性IEquitable<T>.我找到了关于如何为少量属性执行GetHashCode()的多个示例.
public override int GetHashCode()
{
unchecked // Overflow is fine, just wrap
{
int hash = 17;
// Suitable nullity checks etc, of course :)
hash = hash * 23 + field1.GetHashCode();
hash = hash * 23 + field2.GetHashCode();
hash = hash * 23 + field3.GetHashCode();
return hash;
}
}
Run Code Online (Sandbox Code Playgroud)
当我在对象上有数百个属性时,我该怎么回事?
我需要使用x,y,z坐标(仅限整数)对大型bool集进行查找.我试图确定一个块是否可以在x,y,z位置遍历.
目前我正在使用数组bool[,,].然而,这不是非常灵活,并且对于尺寸合适的地图,尺寸很快变得很大.
我认为只有真正价值观的字典会更灵活,内存更少.我创建了一个结构Vector3Int来保存x,y,z值并用作字典键.字典看起来像Dictionary<Vector3Int, bool>.
但是,使用此键进行字典查找似乎比使用x,y,z整数的数组查找慢20-100倍.
有没有更快/更好的方法来做到这一点?我使用查找进行路径查找,因此查找需要非常快,因为单个路径可能有数百/数千个查找.
Vector3Int代码:
public struct Vector3Int
{
public int x,y,z;
public Vector3Int(int x, int y, int z)
{
this.x =x;
this.y=y;
this.z=z;
}
//checks for equality
public static bool operator ==(Vector3Int a, Vector3Int b)
{
return a.x==b.x && a.y ==b.y && a.z ==b.z;
}
public override bool Equals(object obj)
{
return obj is Vector3Int && this == (Vector3Int)obj;
}
public override int GetHashCode ()
{
return x.GetHashCode() ^ y.GetHashCode() ^ z.GetHashCode();
} …Run Code Online (Sandbox Code Playgroud) c# ×9
gethashcode ×4
.net ×2
algorithm ×2
linq ×2
arrays ×1
collections ×1
concurrency ×1
dictionary ×1
guid ×1
hash ×1
hashcode ×1
java ×1
overriding ×1
performance ×1