Programozásról_szubjektíven - Szoftverfejlesztés fórum

Hirdetés

üzenetek

hozzászólások


pmonitor
(aktív tag)

A következő C# kód a delegate-ek használatát mutatja be:
using System.Runtime.InteropServices;

namespace TesztCsharp
{
internal class Delegates
{
static int Main(string[] args)
{
ADD add = Add;
if (add is ValueType) Console.WriteLine("Ertek tipus.\n");
else Console.WriteLine("Referencia tipus.\n");
int sum = add(2, 3);
int sum2 = Add(2, 3);
Console.WriteLine("a + b = {0}\na + b = {1}", sum, sum2);

MessageBox(0, "Tartalom", "Cím", 0);

IntPtr lib = NativeLibrary.Load("user32.dll");
IntPtr addressA = NativeLibrary.GetExport(lib, "MessageBoxA");
IntPtr addressW = NativeLibrary.GetExport(lib, "MessageBoxW");
/*
//Regebbi verziok eseten:
IntPtr lib = LoadLibrary("user32");
IntPtr addressA = GetProcAddress(lib, "MessageBoxA");
IntPtr addressW = GetProcAddress(lib, "MessageBoxW");
*/

MessageBoxA MsgBoxA = (MessageBoxA)Marshal.GetDelegateForFunctionPointer(addressA, typeof(MessageBoxA));
MessageBoxW MsgBoxW = (MessageBoxW)Marshal.GetDelegateForFunctionPointer(addressW, typeof(MessageBoxW));
MsgBoxA(0, "Tartalom_A", "Cím_A", 0);
MsgBoxW(0, "Tartalom_W", "Cím_W", 0);

/*
unsafe
{
var MsgBoxPA = (delegate* unmanaged<int, string, string, int, int>)addressA;
var MsgBoxPW = (delegate* unmanaged<int, IntPtr, IntPtr, int, int>)addressW;
MsgBoxPA(0, "Tartalom_PA", "Cím_PA", 0);
MsgBoxPW(0, Marshal.StringToHGlobalUni("Tartalom_PW"), Marshal.StringToHGlobalUni("Cím_PW"), 0);
}
*/

NativeLibrary.Free(lib);
return 0;
}

[DllImport("user32.dll", CallingConvention = CallingConvention.StdCall, SetLastError = true, CharSet = CharSet.Auto)]
static extern int MessageBox(IntPtr hWnd, String text, String caption, uint type);

[UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet = CharSet.Ansi)]
delegate int MessageBoxA(int hWnd, string lpText, string lpCaption, int uType);

[UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet = CharSet.Unicode)]
delegate int MessageBoxW(int hWnd, string lpText, string lpCaption, int uType);

delegate int ADD(int a, int b);

static int Add(int a, int b)
{
return a + b;
}

/*
//Regebbi verziok eseten:
[DllImport("kernel32", CharSet = CharSet.Ansi)]
extern static IntPtr GetProcAddress(IntPtr hwnd, string procedureName);

[DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
static extern IntPtr GetModuleHandle([MarshalAs(UnmanagedType.LPWStr)] string lpModuleName);

[DllImport("kernel32.dll")]
static extern IntPtr LoadLibrary(string dllToLoad);
*/
}
}

A kimenet:
Referencia tipus.

a + b = 5
a + b = 5

Mint látjuk, a delegate referencia típus. Ha az unsafe kódot használnánk, akkor engedélyezni kell a projektben. A legegyszerűbb használat ez:
static extern int MessageBox(IntPtr hWnd, String text, String caption, uint type);
De azért nem árt, ha a többi lehetőséggel is tisztában vagyunk.


pmonitor
(aktív tag)

Egy példa arra, hogy hogyan lehet átírni a konstansokat. unsafe kód kell hozzá.
string[] strt = Enum.GetNames(typeof(Szinek));
foreach (string item in strt)
{
Console.WriteLine(item);
unsafe
{
fixed (char* ptr = item) { *ptr = 'X'; }
}
}
Console.WriteLine("");

strt = new string[] { "A", "B", "C"};
Console.WriteLine("{0} {1} {2}\n",strt[0], strt[1], strt[2]);

strt = Enum.GetNames(typeof(Szinek));
foreach (string item in strt)
{
Console.WriteLine(item);
}
Console.ReadKey(true);

enum Szinek { Piros = 1, Feher, Zold, Kek, Sarga = 6, Lila, Narancs, Fekete };

A kimenet:
Piros
Feher
Zold
Kek
Sarga
Lila
Narancs
Fekete

A B C

Xiros
Xeher
Xold
Xek
Xarga
Xila
Xarancs
Xekete

Itt először kiíratom a Szinek neveit, majd unsafe kódban módosítom az első karaktert 'X'-re.
Utána strt string tömböt módosítom.
Végül ismét kiíratom a Szinek neveit. Mint látható, itt már a módosított értékeket írja ki.

Az unsafe kóddal majdnem olyan hatékonysággal lehet dolgozni, mint a C-vel. Csak tudni kell, hogy az ember mit csinál benne.


pmonitor
(aktív tag)

Engem zavart, hogy a HashSet<T>-t nem lehet indexelni. Készítettem neki 1 indexelőt. A hatékonysága nem jó, de működik. MyHashSet-nek neveztem el:
MyHashSet<int> myHs = new MyHashSet<int>();
myHs.Add(101);
myHs.Add(102);
myHs.Add(103);
myHs.Add(104);

int i = myHs[3];

Console.WriteLine(i);

public class MyHashSet<T> : HashSet<T>
{
public T this[int index]
{
get
{
List<T> list = new List<T>(this);
return list.Count > index ? list[index] : throw new Exception();
}
}
}

[ Szerkesztve ]


cucka
(addikt)
Blog

Azért nem lehet indexelni, mert a Set nem garantál semmilyen sorrendet. Ez egy halmaz. Egy halmaznak nincs "első eleme" meg "második eleme".

Ha szükséged van sorrendre, akkor létezik SortedSet.

[ Szerkesztve ]


pmonitor
(aktív tag)

Tudom, hogy miért nem lehet indexelni eredetileg. Azért készítettem neki egyet!
Azért mégis jobb/kényelmesebb így használni: int i = myHs[3];, mint foreach-el!!

[ Szerkesztve ]


cucka
(addikt)
Blog

Ha tudnád, akkor nem írtad volna meg ezt a kódot így.
Amikor a set-ből listát csinálsz abban a getterben, ott szintén nincs garantálva az elemek sorrendje.
Tehát nincs semmilyen garancia arra, hogy ez a kód jól fog működni. Az esetek többségében jó lesz, de ez csak a véletlen műve.


pmonitor
(aktív tag)

Csináld meg pl. ezt foreach-el.
int i;
for (i = myHs.Count - 1; i >= 0; --i)
{
if (myHs[i] == 102) myHs.Remove(i);
}
i = myHs[myHs.Count - 1];

Console.WriteLine(i);

Mondjuk ez nem olyan látványos. De amikor osztály példányokkal dolgozol(amelyiknek vmelyik. adattagját/mezőjét kell ellenőrizni, akkor már jobban előjön ennek az előnye. Persze a negatív indexeket is jó lenne ellenőrizni...

[ Szerkesztve ]


cucka
(addikt)
Blog

Egyébként ez a kód mit csinál?
Milyen osztály adattag ellenőrzés?
Milyen negatív indexek?

Ne haragudj, de ezek a szavak külön-külön értelmesek, de nem formálódnak koherens gondolattá.
Csakúgy mint ez a pár soros kód. Értem, hogy mit csinál, csak azt nem, hogy miért. Mi értelme ennek, mit jelent az az i érték amit kiírsz a végén?
(Mert ugye a hashset-edben nincs sorrend definiálva. Tehát az i érték a végén az bármi lehet. Egy szám, jelentés nélkül.)


cucka
(addikt)
Blog

Most jó hangulatban vagyok, szóval itt egy feladat, amiből tanulhatsz valamit.

Adott pár hsz előtt az indexelő megoldásod. És adott ez a for ciklus amit írtál.

Gondold végig, hogy vajon ez a for ciklus mindig garantáltan fel fogja-e dolgozni a hashSet-et összes elemét?

A választ erre már megírtam itt, csak össze kell raknod fejben.

[ Szerkesztve ]


pmonitor
(aktív tag)

Azt csinálja, hogy végig iterál a T típusok példányain a végétől az elejéig. Ha ez a T típus 1 osztály lenne, akkor megnézné, hogy pl. point.X értékei egyeznek-e egy bizonyos értékkel, akkor a feltételnek megfelelő point-okat törölné a myHashSet-ből.

#64. mert a Set nem garantál semmilyen sorrendet..

Ilyen alapon a foreach sem kellene, mert az sem garantál bizonyos sorrendet. Akkor az nem felesleges?

#69
Gondold végig, hogy vajon ez a for ciklus mindig garantáltan fel fogja-e dolgozni a hashSet-et összes elemét?
Igen.

[ Szerkesztve ]


cucka
(addikt)
Blog

A foreach-al végig tudsz iterálni egy collection-ön. Pontosabban bármin, ami implementálja az IEnumerable interfészt.

Az egyetlen dolog, amit egy IEnumerable garantál, hogy írhatsz rá egy foreach-et, ami a collection-öd mindegyik elemét fel fogja dolgozni.

Amivel az IEnumerable nem foglalkozik, és nem is szükséges tudni egy foreachhez, az hogy :
- melyik elem micsoda
- két elem közül melyik a nagyobb
- melyik elem hányadik a sorban

Te valamiért mindenképp Array-ként akarod használni. Az Array egy szűkebb értelmezése a collection-nek, mert mindenképp garantálja, hogy minden elemnek van egy nemnegatív indexe, és az indexekben nincsenek lyukak.

Nyilván az Array az egy Enumerable. De fordítva ez nem igaz.


pmonitor
(aktív tag)

Adott a következő kód:
MyHashSet<Point> myPt = new MyHashSet<Point>();
myPt.Add(new Point(10, 20));
myPt.Add(new Point(15, 20));
myPt.Add(new Point(20, 20));
myPt.Add(new Point(20, 20));

Console.WriteLine(myPt.Count);


int i;
for (i = myPt.Count - 1; i >= 0; --i)
{
if (myPt[i].X == 20) myPt.Remove(myPt[i]);
}
Console.WriteLine(myPt.Count);

i = myPt[myPt.Count - 1].X;

Console.WriteLine(i);


public class MyHashSet<T> : HashSet<T>
{
public T this[int index]
{
get
{
List<T> list = new List<T>(this);
return list.Count > index ? list[index] : throw new Exception();
}
}
}

public class Point
{
public int X; public int Y;

public Point(int x, int y)
{
X = x;
Y = y;
}
}

A kimenet:
4
2
15

Sztem tök jól működik. Az összes olyan myPt-t törölte, ahol X ==20. 2 darab ilyen volt. Látszik, hogy a hossz 4-ről 2-re változott.

[ Szerkesztve ]


cucka
(addikt)
Blog

Mondom jókedvemben vagyok, szóval vegyük végig.
Ott van a metódusod, amivel indexelni tudod a hashset-edet. Amikor azt mondom, hogy hashset[i], akkor
1. a hashset-ből csinálsz egy listát - ugye ez az aminek nem determinált a sorrendje
2. visszatérsz a lista[i]-vel

Namost legyen egy hashsetem, A, B, C értékekkel. Jön a for ciklus, ami végigmegy az elemein

i=0 eset
megcsinálod a listát, az lesz benne, hogy [A,B,C]. visszatérünk a lista[0]-val, ami az A érték.

i=1 eset
megcsinálod a listát, az lesz benne, hogy [B,A,C], visszatérünk a lista[1]-el, ami az A érték

i=2 eset
megcsinálod a lsitát, az lesz benne, hogy [C,B,A], visszatérünk a lista[2]-vel, ami ismét az A érték

végigértünk a for cikluson, az [A,B,C] hashset-ből feldolgoztuk az A értéket 3szor, és a többi értéket nem dolgoztuk fel.

Ezt jelenti az, hogy a egy Set elelein nincs sorrend meghatározva. Erre mondtad hogy érted, de láthatóan nem érted, remélhetőleg így már menni fog.

Szóval innen adódik a köv. feladat, hogy vajon hogy lehet mégis olyan indexelést csinálni egy hashset-re, ami garantáltan működik?

mod: a példa kódodra. Itt a fenti esetben is az lesz, hogy általában a listád az lesz, hogy [A,B,C] és általában működni fog.
Kivéve, amikor nem fog működni, mert jön a háttérben a gc és átrendezi a memóriádat. És akkor majd más lesz a sorrend.

[ Szerkesztve ]


pmonitor
(aktív tag)

De a listát ugyanúgy készíti el minden esetben(ugyanúgy generálja). Ezért nem jó a gondolatmeneted. A törlés után is a sorrend megmarad. De akkor szted. ez a kód miért is működik? De írjál olyan esetet, amikor nem működik.

[ Szerkesztve ]


cucka
(addikt)
Blog

Leírtam az esetet, amikor nem működik.

Amikor te az [A,B,C] hashset-et listává alakítod, akkor az általában az [A,B,C] listát fogja eredményezni. Tehát az indexelésed általában működni fog.

Kivéve amikor nem. Mert jön a gc és átrendezi a memóriádat. Vagy valaki egy másik CLR-en futtatja a kódodat. Vagy beraksz egy D elemet a set-be, és az nem a lista végén fog megjelenni.

Ha az elemek sorrendje nincs garantálva, az azt jelenti, hogy nem írsz olyan logikát, ami azt feltételezi, hogy a sorrend garantálva van. Akkor se, ha általában a sorrend nem szokott változni.

Ez egy egzakt eldönthető kérdés. Vagy sorrendben vannak az elemek, vagy nincsenek sorrendben.
Ha többé-kevésbé az esetek nagy részében általában sorrendben vannak, és kipróbálod, és a sorrend nem változik, és a te gépeden jónak tűnik, na az nem jelent lófaszt se.

[link] itt fel van sorolva az összes interfész, amit a HashSet implementál. Mindegyik garantál valamilyen viselkedést.
Amelyik viselkedést itt látod, azon dependálhatsz.
Amelyiket nem látod, azon nem dependálsz.
Nem olyan bonyolult.

[ Szerkesztve ]


pmonitor
(aktív tag)

Az, hogy jön a GC, az csak a memóriát rendezi át(Átmásolja "A" memóriacímről "B"-be a megadott hosszt). Ez nem változtatja meg az elemek sorrendjét. Na látod ilyenért célszerű lemenni asm-be.

Vagy valaki egy másik CLR-en futtatja a kódodat.

for ciklus közben azt nehéz lenne...

[ Szerkesztve ]


cucka
(addikt)
Blog

De amit tényleg próbálj felfogni, az a következő:

Valami vagy garantálja az elemek sorrendjét, vagy nem garantálja.

És ha nem garantálja, akkor nem írsz olyan kódot, ami csak akkor működik jól, ha ez a garancia teljesül.

Szerintem nem túl bonyolult. Szóval mielőtt lemennél ASM-be, azért próbáld megérteni ezeket az egyszerű logikai összefüggéseket.

[ Szerkesztve ]


pmonitor
(aktív tag)

Értem, hogy mi a gondolatmeneted, csak nem értek vele egyet. Egyébként amikor a hashset-ből listát csinál, akkor az történik, hogy pár byte-ot a hashset ELÉ tesz. Az nem változtatja meg az elemek sorrendjét. A hashset teljes hosszában változatlan marad. Nem random módon működik a ToList() metódus. Annak a kódja(algoritmusa) nem változik.

[ Szerkesztve ]


cucka
(addikt)
Blog

Amit írtam, az nem egy megvitatandó gondolatmenet, hanem egy axioma.
Ha OOP nyelvben fejlesztesz, akkor amit írtam, az egy tény. Ez van.
Elfogadhatod és magadévá teheted ezt a gondolatmenetet, és akkor OOP-ben jobb fejlesztő leszel mint előtte. Már ha akarod, persze, senki se kényszerít.

A másik topikban panaszkodtál, hogy itt senki se segít semmiben, hát tessék, az már rajtad áll, hogy mit kezdesz vele.


pmonitor
(aktív tag)

Ha írsz bármilyen algoritmust, akkor annak a kódja nem változik meg a program futása közben. A kód(algoritmus) ugyanaz marad. A ToString metódus kódja fix. Az nem változik meg attól, hogy 1 iterációban van.
De ha vki nem hisz nekem, akkor egyetlen megoldása marad:
foreach-el végig iterál az elemeken. Az iteráción belül kigyűjti a törlendő elemeket(pl. egy listába), és a foreach után még egyszer végigiterál a kigyűjtött elemeken. És így törli egyesével azokat.
Ha vki hisz nekem, akkor meg úgy csinálja, ahogy mutattam.


pmonitor
(aktív tag)

Egyébként meg pl. az 1D vágás(hátizsák probléma azonos hátizsákkal) esetében nem is készülne egyetlen program sem, mert az optimális megoldást úgy sem találja meg a legtöbb esetben. Ha az axioma alapján indulunk el. De a gyakorlat azt mutatja, hogy készülnek ilyen programok, és még némelyik nem kevés lóvét is kér érte. Tehát az ezt készítő programozók nem az axiomát követik. Pedig ott szinte zéró a valószínűsége, hogy az optimális esetet megtalálják...


pmonitor
(aktív tag)

De ki lenne az az idióta programozó, aki nem úgy valósítaná meg a ToList metódust, hogy:
1: Vagy a hashset első elemétől az utolsó elemig egyesével növelve,
2: Vagy a hashset utolsó elemtől az első elemig egyesével csökkentve.
Ha az én feladatom lenne a ToList megvalósítása, akkor az 1. pontot választanám. És egyébként a foreach is ezt teszi. Biztosan.
Mert végig lehet iterálni ennek a rendező algoritmusnak az iterálási sorrendjében is. Csak kérdés, hogy ki lenne az a félnótás programozó, aki pl. ezt a sorrendet választaná.
Ezért biztos vagyok benne, hogy az én kódom is mindig végigiterál az összes elemen. Attól függetlenül írom ezt, hogy nem axioma.


pmonitor
(aktív tag)

Hááát... A "szakik" szerint a string is érték típus... És ráadásul nem is akárkik szerint. Hanem az ELTE-sek szerint. Ennyit erről...


pmonitor
(aktív tag)

Átírtam a kódot. Én nem találok olyan adatokat, amivel ne működne.
namespace TesztCsharp
{
class HashSets
{
static void Main(string[] args)
{
MyHashSet<Point> myPt = new MyHashSet<Point>();
myPt.Add(new Point(20, 20));
myPt.Add(new Point(15, 20));
myPt.Add(new Point(20, 20));
myPt.Add(new Point(21, 20));

Console.WriteLine("Count = {0}", myPt.Count);
foreach (Point pt in myPt)
{
Console.Write("{0} ", pt.X);
}

int i;
int torl = 20;
Console.WriteLine("\nTorlendo X érték: {0}", torl);
for (i = myPt.Count - 1; i >= 0; --i)
{
Point pt = myPt[i];
if (pt.X == torl) myPt.Remove(pt);
}

Console.WriteLine("\n\nCount = {0}", myPt.Count);
foreach (Point pt in myPt)
{
Console.Write("{0} ", pt.X);
}

if (myPt.Count > 0)
{
i = myPt[myPt.Count - 1].X;
Console.WriteLine("\nUtolso elem = {0}", i);
}
}
}

public class MyHashSet<T> : HashSet<T>
{
List<T> list = new List<T>();
public T this[int index]
{
get
{
if (list.Count != Count) list = new List<T>(this);
return ((list.Count > index) && (index >= 0)) ? list[index] : throw new IndexOutOfRangeException();
}
}

public bool Add(T item)
{
if (base.Add(item))
{
list = new List<T>(this);
return true;
}
else return false;
}

public bool Remove(T item)
{
if (base.Remove(item))
{
list = new List<T>(this);
return true;
}
else return false;
}
}

public class Point
{
public int X; public int Y;

public Point(int x, int y)
{
X = x;
Y = y;
}
}
}

A kimenet pedig ezekkel az adatokkal:
Count = 4
20 15 20 21
Torlendo X érték: 20


Count = 2
15 21
Utolso elem = 21

cucka: Azért köszi a kritikát. A véleményünk nem egyezik, de örülök, hogy leírtad az álláspontod...


pmonitor
(aktív tag)

Sőt! Ez nálam még úgyis működik minden esetben, ha az Add() és a Remove() metódusokban nem készítek új listát, csak 1szerűen ugyanazt a metódust meghívom a listára. Tehát:
public bool Add(T item)
{
if (base.Add(item))
{
list.Add(item);
return true;
}
else return false;
}

public bool Remove(T item)
{
if (base.Remove(item))
{
list.Remove(item);
return true;
}
else return false;
}

Azért az indexelőben benne hagytam a feltételt, ha mégis valami gubanc lenne. De sztem még az sem kellene bele.
Az, hogy egyszer [A,B,C], majd [B,A,C], majd utána [C,B,A] legyen a kimenet, az halmazelméletben megállja a helyét. De állítom, hogy az a halmazelmélet tanár/prof/előadó még életében nem gondolta végig, hogy a gyakorlatban hogy is vannak/lehetnek az adattípusok a memóriában. Ilyent még szándékosan is nehezen lehet generálni.
A gyakorlatban még a List<T>, és a HashSet<T> Add() és Remove() metódusai is ugyanúgy működnek. Csak azt nem tudom, hogy egy programozó miért csinálna olyant, hogy szándkosan permutálja az elemeket random módon. Ez semmiképpen nem reális dolog a valóságban. És azért akik az MS VS C#-ot és a .NET-et implementálták, róluk sem hiszem el, hogy ilyent csinálnának. Ez a halmazelméleti axioma csak olyanok fejében létezik, akik túl komolyan veszik az absztrakciót. Azaz túl elvontak/elméletiek. Gyakorlat meg zéró.


pmonitor
(aktív tag)

1: Ki, vagy mi generálna ilyen összevissza permutációkat?
2: Mennyi a valószínűsége, ha csak általában működne, hogy az pont az én vasam lenne? És ráadásul azon minden alkalommal? Minden példára?
3: Mennyi a valószínűsége annak, hogy más gépére az MS más algoritmusokat írna? És annak, hogy direkt az én gépemre írjon más algoritmusokat, mint más gépére? Nem hiszem, hogy velem kivételezne az MS.

De bebizonyíthatjátok, hogy ti tudjátok jól. Írjatok olyan esetet, amikor nem működik az elvártnak megfelelően!

Közben egy véletlen elírást javítanék. Ezt írtam:
A gyakorlatban még a List<T>, és a HashSet<T> Add() és Remove() metódusai is ugyanúgy működnek.
Ezt én úgy értettem, hogy mindegyik Add() metódus a végére teszi az új elemet. De természetesen a HashSet Add() metódusa szigorúbb a List Add() metódusánál. De a kódon látszik, hogy így csináltam, csak a rizsa részében fogalmaztam pontatlanul.


pmonitor
(aktív tag)

A "Programozás topic"-ban elég vád ért engem. Ez sarkallt arra, hogy itt reagáljak rá(mivel ott nem tudok - a modi hatalmasabb nálam). Én továbbra is állítom, hogy az itt szereplő kódok jól működnek.
A moderátor ezt állította:
kreal egy Point classt. szoval ez szep meg jo, csak koze nincs a Sethez.

Ezzel egy hibát követett el(de az fatális). Ugyanis van köze a Sethez. Nem is kevés. Csak annyi a lényeg, hogy mivel nem írtam át az Equals() metódust, ezért a referenciákat veszi halmaznak. És természetesen azok egyenlőségét vizsgálja. Tehát nagyon is van köze a Sethez. Ha a Main() metódus elejét a következőkre módosítjuk, akkor ez megvilágítja, amiről eddig írtam:
MyHashSet<Point> myPt = new MyHashSet<Point>();
Point pnt = new Point(20, 20);
Point pnt2 = pnt;
Point pnt3 = new Point(19, 20);
Point pnt4 = new Point(21, 20);
myPt.Add(pnt);
myPt.Add(pnt2);
myPt.Add(pnt3);
myPt.Add(pnt4);

Ennek a kimenete:
Count = 3
20 19 21
Torlendo X érték: 20


Count = 2
19 21
Utolso elem = 21

Itt tökéletesen látszik, hogy az elején 4 helyett 3 különböző érték van csak: 20 19 21
Ez a Point pnt2 = pnt; sor miatt van. Mivel ennek a kettőnek azonos a referenciája, ezért a kettőjük helyett csak az egyikük szerepel.

De ha a Point osztálytba beletesszük az Equals() metódust, akkor így néz ki:
public override bool Equals(object obj)
{
if (obj == null)
{
return false;
}
if (!(obj is Point))
{
return false;
}
return (this.X == ((Point)obj).X) && (this.Y == ((Point)obj).Y);
}

public override int GetHashCode()
{
return X.GetHashCode() ^ Y.GetHashCode();
}

és ha a pnt-ket így módosítjuk:
Point pnt = new Point(20, 20);
Point pnt2 = new Point(15, 20);
Point pnt3 = new Point(20, 20);
Point pnt4 = new Point(21, 20);

akkor a kimenet:
Count = 3
20 15 21
Torlendo X érték: 20


Count = 2
15 21
Utolso elem = 21

Az elején itt is csak 3 érték van. Mivel pnt és pnt3 egyenlő.
Tehát egyértelműen látszik, hogy a moderátor nem írt igazat azzal, hogy a Sethez köze sincs. De amiket itt írtam, azokra továbbra sincs válasz.
A mostani kód így néz ki:
namespace TesztCsharp
{
class HashSets
{
public static void Main(string[] args)
{
MyHashSet<HsPoint> myHashSet = new MyHashSet<HsPoint>();
myHashSet.Add(new HsPoint(20, 20));
myHashSet.Add(new HsPoint(19, 20));
myHashSet.Add(new HsPoint(20, 20));
myHashSet.Add(new HsPoint(15, 20));

Console.WriteLine("Count = {0}", myHashSet.Count);

foreach (HsPoint pt in myHashSet)
{
Console.Write("{0} ", pt.X);
}

int i;
int torlendo = 20;
Console.WriteLine("\nTorlendo X érték: {0}", torlendo);
for (i = myHashSet.Count - 1; i >= 0; --i)
{
HsPoint pt = myHashSet[i];
if (pt.X == torlendo) myHashSet.Remove(pt);
}

Console.WriteLine("\n\nCount = {0}", myHashSet.Count);
foreach (HsPoint pt in myHashSet)
{
Console.Write("{0} ", pt.X);
}

if (myHashSet.Count > 0)
{
i = myHashSet[myHashSet.Count - 1].X;
Console.WriteLine("\nUtolso elem = {0}", i);
}
}
}

class MyHashSet<T> : HashSet<T>
{
List<T> myList = new List<T>();

public T this[int index]
{
get
{
return ((myList.Count > index) && (index >= 0)) ? myList[index] : throw new IndexOutOfRangeException();
}
}

public bool Add(T item)
{
if (base.Add(item))
{
myList.Add(item);
return true;
}
else return false;
}

public bool Remove(T item)
{
if (base.Remove(item))
{
myList.Remove(item);
return true;
}
else return false;
}
}

class HsPoint
{
public int X; public int Y;

public HsPoint(int x, int y)
{
X = x;
Y = y;
}

public override bool Equals(object obj)
{
if (obj == null)
{
return false;
}
if (!(obj is HsPoint))
{
return false;
}
return (this.X == ((HsPoint)obj).X) && (this.Y == ((HsPoint)obj).Y);
}

public override int GetHashCode()
{
return X.GetHashCode() ^ Y.GetHashCode();
}
}
}

De ebben már csak finomítások vannak.


proci985
(MODERÁTOR)
Blog

Topikot zártam. Programozás topik itt.

A kezdő hozzászólás témafelvetése gyakorlatilag a computer science / software engineering (vagy általánosan, informatics mint gyűjtőterület) beemelése lett volna az aktív témák közé, olyan témákkal, mint optimizáció, elosztott programozás, jogi/etikai vonatkozások, illetve cybersecurity. Ezt kb egy szakirányú BSc lefedi.

Ehhez képest a topik május vége óta átment az említett Programozás topik párhuzamos topikjába, így zárom.

üzenetek