[C#] Vill att en klass ska "fungera som" en boolean

Permalänk
Medlem

[C#] Vill att en klass ska "fungera som" en boolean

Jag anser mig själv lärt mig ganska mycket om C# nu när jag hållt på med det ganska aktivt i ca. 6 månader. Men en sak som jag kommit på mig själv vilja kunna göra är följande:

class Test { public bool[] list = new bool[true, false, true, false] public Test() { } } class Main { static void Main(string[] args) { var test = new Test(); if (test) DoThis(); } private void DoThis() { // Something here } }

Problemet som ni kanske ser är att jag givetvis inte bara kan skriva if (test), men jag vill kunna göra det. Finns det något sätt att lösa detta på? Istället för att behöva göra en property och sedan anropa den på objektet?

Permalänk
Medlem

Du behöver använda en operator för det. Läs mer om det här.

Men jag tror du behöver använda true/false operatorn, du kan läsa mer om det här.

Det är riktigt användbart att lära sej koda med operatorer. Du kan ex. skapa större än och mindre än operatorer mellan objekt, som returnerar sant/falskt värde.
I C++ kursen jag hade, körde vi med djup klon via tilldelningsoperatorn, dvs. objekt1 = objekt2, som då istället för att objekt1 blev samma som objekt2, så fick objekt1 samma värden på sina attribut, och unika underobjekt, som hade samma värden på dess attribut.

Det finns så många möjligheter med det.

Permalänk
Medlem

Det skulle ju vara bra med lite mer info om vad listan ska vara till för och lite mer detaljer kring det. Blir lättare att hjälpa och tipsa...

Om man tittar på din rubrik så vill du att klassen ska vara som en bool. Då tipsar jag dig om properties.

Visa signatur

Fulburken:
| I9 9900K
| Gigabyte Aorus Z390 AORUS MASTER
| Asus RTX 3090 Strix OC

Permalänk
Medlem

Om du vill kunna skriva som du gör nu så måste Test() returnera false eller true

Visa signatur
Permalänk
Medlem

Efter att ha läst länkarna NickoB gav mig så kom jag fram till en lösning. (Även rättat massa fel i min kod jag visade, trött samt skrev det i notepad ^^). Detta var min lösningar

class Test { public bool[] list = new bool[] { true, true, true, true }; public static bool operator true(Test x) { return x.list.All(y => y == true); } public static bool operator false(Test x) { return x.list.All(y => y == true); } public Test() { } } class Program { static void Main(string[] args) { var test = new Test(); if (test) DoThis(); } }

Här kommer den i if-satsen kolla på de assignade värdena true, true, true och true. Om alla är true returnera true. Grymt, nu kan jag applicera denna till ett par av mina klasser i mitt projekt :). Tack!

Permalänk
Hedersmedlem
Skrivet av Zelloxy:

Efter att ha läst länkarna NickoB gav mig så kom jag fram till en lösning. (Även rättat massa fel i min kod jag visade, trött samt skrev det i notepad ^^). Detta var min lösningar

...

Här kommer den i if-satsen kolla på de assignade värdena true, true, true och true. Om alla är true returnera true. Grymt, nu kan jag applicera denna till ett par av mina klasser i mitt projekt :). Tack!

Dina operators för true och false är identiska. Antar att det är en liten miss?

Visa signatur

Asus B550M-Plus / Ryzen 5800X / 48 GB 3200 MHz CL14 / Asus TUF 3080 OC / WD SN850 1 TB, Kingston NV1 2 TB + HDDs / Corsair RM650x / Acer XB271HU (1440p165) / LG C1 55"
Mobil: Moto G200

Permalänk
Medlem
Skrivet av Thomas:

Dina operators för true och false är identiska. Antar att det är en liten miss?

Hehe ahh givetvis. Ena ska ju vara false.

Permalänk
Hedersmedlem

Gick tydligen att lösa.

Men designmässigt, är det motiverat att använda sig av detta?
Vad betyder det att ett objekt kan vara sant eller falskt? Generellt sätt.
Jag ser inget bra svar och skulle undvika att använda det.

Visa signatur

Forumregler | Feedbackforumet | Något som behöver modereras? Tryck på Anmäl inlägget och ge en anledning, någon moderator kommer granska inlägget och göra (egen) bedömning
"Fate. Protects fools, little children and ships named Enterprise." - Riker - ST:TNG

Permalänk
Medlem
Skrivet av Aqualize:

Gick tydligen att lösa.

Men designmässigt, är det motiverat att använda sig av detta?
Vad betyder det att ett objekt kan vara sant eller falskt? Generellt sätt.
Jag ser inget bra svar och skulle undvika att använda det.

Nej det vet jag inte. Jag vill bara lära mig det, samt att det kanske ser lite mer städat ut i koden att skriva till "if (value)" istället för "if (value.isValid)"?

Permalänk
Medlem
Skrivet av Zelloxy:

Nej det vet jag inte. Jag vill bara lära mig det, samt att det kanske ser lite mer städat ut i koden att skriva till "if (value)" istället för "if (value.isValid)"?

Varför använda operatoröverlagring, istället för metoder för att lösa problemen?
Istället för att skriva varför, så kör jag några exempel:
Till vänster är metod/egenskap lösningen, till höger har det ersatts med en operator som vi vanligtvis använder:

-- Metodlösning -- -- Operatorlösning -- if (myObject.isValid()) vs. if (myObject) if (myObject.isValid) vs. if (myObject) if (myObject.dateGreaterThan(otherValue)) vs. if (myObject > otherValue) if (myObject.equals(otherValue)) vs. if(myObject == otherValue) (eller varför inte !=, <=, >= osv) if(myObject.dateGreaterThan(dateObject)) vs. if (myObject > dateObject) myObject.copyValuesFrom(otherValue); vs. myObject = otherValue; myObject.addOne(); vs. myObject++; myObject.additionToThisOne(otherObject); vs. myObject += otherValue; myObject.setAttribute(5); vs. myObject = 5;

Permalänk
Medlem
Skrivet av Zelloxy:

Nej det vet jag inte. Jag vill bara lära mig det, samt att det kanske ser lite mer städat ut i koden att skriva till "if (value)" istället för "if (value.isValid)"?

Skrivet av NickoB:

Varför använda operatoröverlagring, istället för metoder för att lösa problemen?
Istället för att skriva varför, så kör jag några exempel:
Till vänster är metod/egenskap lösningen, till höger har det ersatts med en operator som vi vanligtvis använder:

-- Metodlösning -- -- Operatorlösning -- if (myObject.isValid()) vs. if (myObject) if (myObject.isValid) vs. if (myObject) if (myObject.dateGreaterThan(otherValue)) vs. if (myObject > otherValue) if (myObject.equals(otherValue)) vs. if(myObject == otherValue) (eller varför inte !=, <=, >= osv) if(myObject.dateGreaterThan(dateObject)) vs. if (myObject > dateObject) myObject.copyValuesFrom(otherValue); vs. myObject = otherValue; myObject.addOne(); vs. myObject++; myObject.additionToThisOne(otherObject); vs. myObject += otherValue; myObject.setAttribute(5); vs. myObject = 5;

För mig antyder koden if (whatever) { ... att whatever är en bool; det är inte helt klart att referensen pekar på ett komplext objekt. Samma sak med överlagringen av = på .copyValuesFrom(...) (går det verkligen? känns farligt på annat än structs..)

För jämförande operatorer (<, >, !=, == etc) tycker jag överlagring är jättepraktiskt!

Visa signatur

Kom-pa-TI-bilitet

Permalänk
Medlem
Skrivet av Teknocide:

För mig antyder koden if (whatever) { ... att whatever är en bool; det är inte helt klart att referensen pekar på ett komplext objekt. Samma sak med överlagringen av = på .copyValuesFrom(...) (går det verkligen? känns farligt på annat än structs..)

För jämförande operatorer (<, >, !=, == etc) tycker jag överlagring är jättepraktiskt!

Det hänger väl mer på hur tydlig namngivningen är av alla variabler/attribut i koden, samt hur insatt man är i koden.

Ex.
Döper du enligt detta:

bool var1; MyClass var2; void myFunction() { if (var1 && var2) { ... } }

Så kommer den som läser det ha svårt att se vad var1 och var2 är för något. Detta är inte heller ett bra sätt att namnge variabler/attribut.
Samma sak som att namnge variabler/attribut med a, b, c, d. Endast den som är insatt i koden kommer förstå, men ändå ha svårt ibland.

Tar man däremot följande två:
Det första är en form av "Hungarian Notation":

bool bVar1; MyClass oVar2; ...

Så ser man sedan i koden att "bVar1" är ett bolskt värde (då man följer reglerna att alla bolska variabler/attribut döps med "b", integer med i, double med d osv.) Då man kommer till if satsen, ser man tydligt sedan att det är ett boolskt värde samt ett objekt som kontrolleras.

Ett annat sätt att döpa, är med ord som beskriver vad variablen/attributet är för något:

bool IsGood; MyClass InfoObject;

Här ser man igen i koden att "InfoObject" är ett objekt, och IsGood borde vara något boolskt värde (lite dåliga namn just nu, men som exempel).

Citerar från Wikipedia istället:

a = b * c;

vs.

weekly_pay = hours_worked * pay_rate;

Så det jag säger är. Allt beror på hur du namnger allting i koden. Dålig namngivning av variabler/attribut, medför att man får svårt att förstå koden.
Jag läste förut en artikel, att namnge med tydliga namn (sista kodexemplet), så en läsare förstår vad koden gör. Och att behöva lägga till kommentarer i sådan kod, medför att man misslyckats i sina namngivningar.

Då jag kodar blir det vanligtvis Hungarian Notation. Men jag håller på att försöka byta till att döpa enligt funktion/användning, för att se hur bra det går.

Permalänk
Medlem
Skrivet av NickoB:

Det hänger väl mer på hur tydlig namngivningen är av alla variabler/attribut i koden, samt hur insatt man är i koden.
...

Just "whatever" är helt klart inget bra variabelnamn; det var en placeholder för vad än variabeln än kan tänkas heta på riktigt.

I boolean-fallet spelar det ingen roll vad du döper din variabel till, det blir ändå otydligt att det rör sig om ett fullt objekt (hungarian notation bör undvikas helt i statiskt typade språk tycker jag):

TransactionResult transactionResult = query.ProcessTransaction(); if (transactionResult) // om transactionResult vad? { ...

TransactionResult transactionIsOk = query.ProcessTransaction(); if (transactionIsOk) // vad signifierar att transaktionen gått igenom? { double rest = transactionIsOk.Outstanding; // metodanrop på bool-liknande variabel ... } else { Log(transactionIsOk.ErrorCode); // felkod på "ok-variabel" ser väldigt skumt ut ...

Jämfört med

if (transactionResult.Status == StatusCode.TransactionOk) { ...

När det kommer till överlagringarna av större-/mindre-än/är-lika-med får man direkt översikt över vad som jämförs, även om man inte ser hur jämförelsen genomförs:

if (selectedDate == User.Birthday) ...

Visa signatur

Kom-pa-TI-bilitet

Permalänk
Medlem
Skrivet av Teknocide:

Just "whatever" är helt klart inget bra variabelnamn; det var en placeholder för vad än variabeln än kan tänkas heta på riktigt.

I boolean-fallet spelar det ingen roll vad du döper din variabel till, det blir ändå otydligt att det rör sig om ett fullt objekt (hungarian notation bör undvikas helt i statiskt typade språk tycker jag):

TransactionResult transactionResult = query.ProcessTransaction(); if (transactionResult) // om transactionResult vad? { ...

TransactionResult transactionIsOk = query.ProcessTransaction(); if (transactionIsOk) // vad signifierar att transaktionen gått igenom? { double rest = transactionIsOk.Outstanding; // metodanrop på bool-liknande variabel ... } else { Log(transactionIsOk.ErrorCode); // felkod på "ok-variabel" ser väldigt skumt ut ...

Jämfört med

if (transactionResult.Status == StatusCode.TransactionOk) { ...

När det kommer till överlagringarna av större-/mindre-än/är-lika-med får man direkt översikt över vad som jämförs, även om man inte ser hur jämförelsen genomförs:

if (selectedDate == User.Birthday) ...

Jag kan förstå varför du inte anser att det fungerar.
Men jag ser det såhär. I många fall skulle det inte fungera, men det kan finnas fall där man skulle kunna dra nytta av detta.
Det är lättare att visualisera fall då jämförelseoperatorerna är användbara. Men det kan finnas fall där det kommer vara mer användbart att kunna returnera true/false från en klass.

Ex. säg du har skapat en klass som behandlar nedtryckning av en tangent. Varje gång du trycker ned en tangent, så ändras ett boolskt attribut till true. Då man släpper tangenten, så ändras det till false. Men man vill även ha möjligheten att låsa tangenten, så klassen returnerar true ända tills man tryckt ned och släppt tangenten x gånger.
För att se om denna klass anger om tangenten är nedtryckt, så finns det två sätt. Det ena, med en metod, ex. "if (keyA.isKeyDown())", den andra med operatorn true/false, dvs. "if (keyA)" (alt. "if (keyA == true)").

Jag skulle i detta fallet föredra att använda den andra lösningen. Det ger mindre kod, och klassen används bara till en sak, lagra och föra vidare om tangenten är nedtryckt eller ej. Då man sitter med tiotusentals rader kod att läsa, så kan det vara underlättande att ha mindre kod framför sej, så länge den är tydlig.

Permalänk
Avstängd

Jag håller med Teknocide, ingen bra använding av operatorer att få komplexa typer att bete sig som en bool. Dock kan det ibland vara okej att tilldela en komplex typ via en explexit operator

public static explicit operator MyType(bool initialState)

MyType myType = false;

Tycker iof att det blir tydligare med en statisk Create-method på den komplexa typen istället

var myType = MyType.Create(false);

Ett problem vi hade i ett projekt som var lite större (20 utvecklare) var att efter ett tag fanns det ingen standard för vad == och equels betyder. I vissa fall var den inte överlagrad och gick på referensen och i andra fall var den överlagrad och nån intern logik styrde vad som var lika. Detta skapade en del buggar då vissade mindre nogräknade utvecklare i projektet ofta inte orkade bry sig att att hur dubbelkolla hur operatorn var implementerad

Visa signatur