Archiwum kategorii: C# / Csharp

C# – walidacja maila

Żeby sprawdzić poprawność adresu email, wcale nie trzeba męczyć się ze skomplikowanymi wyrażeniami regularnymi. W C# z pomocą przychodzi klasa MailAddress. Oczywiście jest to rozwiązanie wysokopoziomowe i wolne (rzuca wyjątki). Zapewnia jednak czytelność kodu.

Przykład (zaczerpnięty ze StackOverflow):

bool IsValid(string emailaddress)
{
  try
  {
    MailAddress m = new MailAddress(emailaddress);
    Console.WriteLine("TRUE" + "\t" + emailaddress);
    return true;
  }
  catch
  {
    Console.WriteLine("FALSE" + "\t" + emailaddress);
    return false;
  }
}

I testy:
IsValid("ok@ok.pl");
IsValid("dolores.ryba@poczta-n.pl");
IsValid("dolores.ryba@poczta.odlotowa.pl");
IsValid("dolores.ryba@a.b.c.d.pl");
IsValid("psikus@dot.dot.dot..pl");
IsValid("@");
IsValid("");
IsValid(null);
IsValid("bad@");
IsValid("@wolf");
IsValid("@poczta.pl");
IsValid("cokolwiek");

Czytaj dalej

C# – jak używać nullable i parsować je do typów prostych

Typy nullable to bardzo sympatyczne zwierzęta. Poza klasycznymi wartościami umożliwiają przypisanie zmiennym prostym niedozwolonej dla nich wartości null – zupełnie jak dla typów referencyjnych.

Do czego można tego użyć? Pierwsza moja styczność z nullable miała miejsce w zamierzchłych czasach studenckich praktyk. Używałam wtedy nullable do przechowywania wartości z pól w formatce (we współpracy z TryParse). Niedawno natomiast zastosowałam nullable int w liście argumentów do metody – użytkownik ma możliwość pominięcia niektórych wartości (wstawienie -1 czy 0 nie rozwiązywało sprawy, gdyż były to również wartości znaczące).

Jak zachowują się takie nullable w prawdziwym życiu? Jak najprościej skonwertować je do typu prostego?

Proste demo – dzięki zastosowaniu default nie ma konieczności używania Parse ani TryParse:

var nullables = new List<int?> {null, -1, 0, 1};
foreach (var nullable in nullables)
{
  var intable = nullable ?? default(int);//magiczna linia
  Console.WriteLine("{0} \t-> {1}", nullable, intable);
}

Oraz wynik:
null -> 0
-1 -> -1
0  -> 0
1  -> 1

C# – Mierzenie czasu wykonania metod

Mierzenie czasu wykonania metod w C#. Bardzo proste i sprawnie działające. Ostatnimi czasy używam głównie do porównywania wydajności implementacji różnych podejść, które przyjdą mi do głowy.


var watch = Stopwatch.StartNew();

//tu metody, których czas mierzysz

watch.Stop();

var elapsedMs = watch.ElapsedMilliseconds;

var czekaj = true;//tu ustaw sobie pułapkę* i odczytaj wartość ze zmiennej elapsedMs

* pułapka – niezmiennie cieszy mnie to polskie tłumaczenie breakpointa 😉

Sprawdzanie czy checkbox jest zaznaczony w Selenium (C#)

Każdy z obiektów znalezionych przez Selenium jest standardowym obiektem typu WebElement. Udostępnia on następujące metody (których wartość zwracana jest typu bool):

  • displayed – element jest widoczny.
  • enabled – element jest aktywny – można go kliknąć, wpisać mu wartość itd. W praktyce każdy element dostępny na stronie ma stan enabled, gdyż jest to stan domyślny. „Wyłączyć” można go jedynie poprzez celowe dodanie do HTML atrybutu disabled. Element z takim atrybutem będzie „wyszarzony”.
  • checked – element jest zaznaczony. Dotyczy pól typu input – zarówno typu radio jak i checkbox.

Kawałek kodu HTML-owego, do którego zastosuję Selenium:


<html>
<body>
<form>
<input type="checkbox" />
</form>
</body>
</html>

Oraz fragment kodu C# z wykorzystaniem Selenium:


[Test]
public void CheckboxIsChecked()
{
  driver.url="file:///C:/DOCUMENTS/test.html";
  var el = driver.FindElement(By.TagName("input"));
  var before = el.Selected;//false
  el.Click();
  var after = el.Selected;//true
}

C#: czym różni się First od FirstOrDefault

Stosowanie wyrażeń lambda i LINQ może w znaczący sposób skrócić kod.

Jednym z częściej używanych funkcji jest funkcja pozwalająca wybrać pierwszy element z kolekcji (może posortowanej wcześniej funkcją Sort(), może potraktowanej wyrażeniem Where()). Do wyboru mamy użycie funkcji First() lub FirstOrDefault(). Czym się różnią?

First() zwraca pierwszy argument z listy. Jeśli lista jest pusta, rzucany jest wyjątek.

FirstOrDefault() zwraca pierwszy argument z listy. Jeśli lista jest pusta, zwracany jest element domyślny.

A jaki to jest element domyślny?

Dla typów prymitywnych typu int – wartość domyślna to 0. Dla typów obiektowych – null.

Całość można łatwo przetestować. Zrobiłam sobie np. taki obiekcik, żeby za jednym zamachem sprawdzić zachowanie się na obiekcie, jak i na incie:

class IntWrapper
{
  public readonly int IntValue;
  public IntWrapper(int intValue)
  {
    IntValue = intValue;
  }
}

I kod testujący:

var list = new List<IntWrapper> {new IntWrapper(5), new IntWrapper(10), new IntWrapper(15)};
/*var result1 = (from r in list
              where r.IntValue.Equals(200)
              select r).First(); */ //exception!

var result2 = (from r in list
              where r.IntValue.Equals(200)
              select r).FirstOrDefault();//default value: null

var list2 = new List<int> { 5, 10, 15 };
/*var result3 = (from r in list2
              where r.Equals(200)
              select r).First();*/ //exception!

var result4 = (from r in list2
              where r.Equals(200)
              select r).FirstOrDefault();//default value: 0

Selenium: Exception „Compound class names are not supported”

Today something about one of exceptions that can occure in Selenium PageFactory.

IllegalLocatorException was unhadled by user code.
An exception of type „OpenQA.Selenium.IllegalLocatorException” occured in WebDriver.dll but was not handled in user code.
Additional information: Compound class names are not supported. Consider searching for one class name and filtering the results.

In my case, this exception was thrown in line:

PageFactory.InitElements(webDriver, pageElement);

This is probably a bug in Selenium. Solution is easy: just do not use:

[FindsBy(How=How.ClassName, Using="name_of_class"]

Instead of ClassName, try to use Css Selectors:

[FindsBy(How=How.CssSelector, Using=".name_of_class"]

Remember about a dot!

Asert w NUnit

Jednym z bardziej elementarnych składników testów są asercje, umożliwiające sprawdzenie, czy spełnione są warunki testu.

W NUnicie dostępnych jest wiele różnych asercji. Najprostsza to:

Assert.AreEqual

To jednak nie wszystko. NUnit oferuje cały wachlarz asercji – warto spojrzeć w dokumentację [equalConstraint][assertions].

Bardzo fajną opcją jest na przykład sprawdzenie, czy kolekcja jest posortowana:

var notSorted = new List<decimal>();

notSorted.Add(12.3);

notSorted.Add(5.5);

notSorted.Add(100);

Assert.That(notSorted, Is.Ordered);//Fail

Poza klasycznymi asercjami NUnit oferuje też np. StringAsert, CollectionAsert itd.

Przekazywanie parametrów do funkcji – Java kontra C#

Parametry przekazywane do funkcji w Javie są przez wartość, co oznacza że wewnątrz funkcji operujemy na kopii obiektu. I kropka. W przypadku typów prostych faktycznie nie ma problemu:

int mainInt = 60;
System.out.println("mainInt before changes: " + mainInt);
m.changePrimitive(mainInt);
System.out.println("mainInt after changes: " + mainInt);
public void changePrimitive(int localInt){
localInt = 3;
System.out.println("localInt in function: " + localInt);
}

mainInt before changes: 60
localInt in function: 3
mainInt after changes: 60

W przypadku typów obiektowych (referencyjnych) również kopiowany jest obiekt, lecz w praktyce wygląda to nieco inaczej niż w przypadku typów prostych. Czytaj dalej

C# i string contains, equals

Wpis z kategorii – C# dla początkujących.

Tak się składa, że po wielu miesiącach pracy raczej w środowisku javowym, odświeżam sobie C#. Jako że nie do końca ufam swojej pamięci oraz nie uznaję czegoś takiego jak „wiedza teoretyczna” – każdą rzecz muszę doświadczalnie sprawdzić. Programując, często mam otwartą drugą instancję Visuala, w której testuję, czy aby na pewno dana funkcja zachowa się tak, jak podejrzewam. Przeważnie funkcje są grzeczne, a moja pamięć całkiem niezła;) Wolę jednak sprawdzić te drobiazgi, niż potem zastanawiać się, dlaczego mój „produkcyjny” całkiem-duży-kawałek-programu nie działa.

Dziś o stringach w C#, konkretnie o ich porównywaniu i sprawdzaniu, czy string zawiera inny napis.

var part = "this";
var full = "this is some text";
Console.WriteLine(full.Contains(part));//true. Nic nadzwyczajnego.

// Contains jest wrażliwy na wielkości znaków:
Console.WriteLine(full.ToUpper().Contains(part));//false
Console.WriteLine(full.Contains(part.ToUpper()));//false
Console.WriteLine(full.Contains(part.ToUpperFirstLetter()));//false
Console.WriteLine(full.ToUpperFirstLetter().Contains(part));//false

Metoda ToUpperFirstLetter() to Extension method – jej szkic znalazłam na StackOverflow, a oto pełna implementacja:

public static class Extension
{
  public static string ToUpperFirstLetter(this string value)
  {
    return (string.IsNullOrEmpty(value)) ?
      String.Empty
      : (value.First().ToString().ToUpper() + value.Substring(1));
  }
}

Analogicznie jak Contains zachowuje sie metoda Equals.