niedziela, 3 marca 2013

Dziedziczenie w c#

Co jakiś czas napotykam na problemy związane z Co- i Contra- wariancją, więc postanowiłem troszkę pobawić się z .NETem. Chciałbym przedstawić dlaczego jest z tym taki problem. Niech poniższy wpis będzie wstępem do większego zagadnienia.
Stwórzmy 2 klasy. Jedna (B) będzie dziedziczyła po drugiej (A)
class A
{
}
 
class B : A
{
}

Aby poprawić czytelność stwórzmy extension method, która będzie określała czy jeden typ dziedziczy od drugiego typu:
 public static class TypeExt
{
 public static bool IsFromType<T>(this Type type)
 {
     return typeof(T).IsAssignableFrom(type);
 }
}

Teraz możemy sprawdzić co zwróci nam ta metoda.
     Console.WriteLine(typeof(A).IsFromType<A>()); //true 
     Console.WriteLine(typeof(B).IsFromType<A>()); //true 
     Console.WriteLine(typeof(A).IsFromType<B>()); //false 

Sprawdzamy jak będzie dla typów generycznych.
 Console.WriteLine(typeof(List<B>).IsFromType<List<B>>()); //true
 Console.WriteLine(typeof(List<B>).IsFromType<IEnumerable<B>>()); //true

Typy generyczne są tak samo traktowane jak 'normalne' typy. Ale co będzie, kiedy argumenty w typach generycznych będą różne lub jeden argument będzie dziedziczony po drugim??
    Console.WriteLine(typeof(List<B>).IsFromType<List<A>>()); //false

Nawet jeżeli typ generyczny będzie taki sam, argumenty w typie generycznym będą inne, ale w relacji dziedziczenia to nie ma zależności. Wtedy musimy porównywać argumenty tych typów generycznych.
public static bool IsGenericArgFromType<T>(this Type type)
{
   var args1 = typeof(T).GetGenericArguments();
   var args2 = type.GetGenericArguments();

   return args1.Length == args2.Length &&
      args1.Zip(args2, (arg1, arg2) => new { arg1, arg2 })
      .All(x => x.arg1.IsAssignableFrom(x.arg2));
}

Console.WriteLine(typeof(List<B>).IsGenericArgFromType<List<A>>()); //true
Console.WriteLine(typeof(List<string>).IsGenericArgFromType<List<object>>()); //true
Pomimo tego, że argumenty w typie generycznym są w relacji dziedziczenia (przyporządkowania) to te dwa type nie są przyporządkowane do siebie. Taki sam problem jest, gdy mamy listę stringów i listę obiektów. W naturalny sposób lista stringów powinna być przyporządkowana do listy obiektów, ale tak nie jest.

SMART - nadużywany akronim

Mam wrażenie, że akronim SMART jest nadużywany. Wszyscy chcą teraz być smart - mądrzy, eleganccy, błyskotliwi, zwinni i sprytni. Więc słówko SMART bardzo łatwo staje się popularne, a zasada o tej samej nazwie ma coraz większą rzeszę zwolenników.



Ostatnio zaglądnąłem pod hasło SMART na Wikipedii, aby sprawdzić ile jest słówek rozwijających ten akronimem. Z tych wszystkich kombinacji można rozwinąć akronim na 13 824 sposobów. Jak jeszcze dołożymy literki ER to jest 580 608 sposobów. Przykład można zobaczyć w poniższym pliku. Wydaje mi się, że najważniejsze nie są literki, ale jaki przekaz niesie dana literka.



Już wcześniej pisałem o tym, że metoda SMART nie wystarcza w realizowaniu celów, ale uważam, że jest bardzo dobrą metodą przy wyznaczaniu celów.

sobota, 2 marca 2013

Zamykanie Windows 8

Musze się przyznać, że jak pierwszy raz uruchomiłem Windows 8 to nie wiedziałem, gdzie jest przycisk do zamykania komputera. Po pewnym czasie w końcu znalazłem. Jeżeli jesteś użytkownikiem Windows 8, to miałeś może taki problem jak ja??



W każdym razie nie o problemach szukania przycisku chciałbym napisać, ale o szybkim zamykaniu systemu.
Na samym początku stwórz skrót ma pulpicie.

Jako program wykonywalny wpisz:

shutdown.exe /s /t 00

Inne opcje są podane na tej stronie.

Polecam wybranie sobie ikonki.


Zaznacz sobie prawym przyciskiem myszy i wybierz "Przypnij do ekranu startowego" ("Pin to Start").



W menu Start przenieś przycisk tam gdzie chcesz. Oczywiście możesz dodać inne opcje zamykania (np. restartowanie).


Na końcu możesz jeszcze usunąć te skróty, które stworzyłeś na pulpicie - usunięcie ich nie wpływa na funkcjonalność okna Start.

sobota, 16 lutego 2013

Mam dość SVN

Mam dość SVN

Usuwam go i już.
gci c:\ -include .svn -Recurse -Force | 
   Remove-Item -Recurse -Force

poniedziałek, 28 stycznia 2013

Algorytmy w finansach

Były już matematyczny Ted o wyszukiwarce wolframalpha, to teraz filmik TED z branży finansowej. Filmik przedstawia jak w dzisiejszych czasach w "prosty" sposób analizuje się całą giełdę oraz dlaczego firmy chcą być blisko giełdy.











sobota, 19 stycznia 2013

Dzielenie listy na części (chunk)

Tyle razy już pisałem metodę dzielącą listę (IEnumerable) na części, że postanowiłem zamieścić kod od razu na blogu. Przypuszczam, że jeszcze niejeden raz będę musiał napisać ten sam kod.
public const int MaxHandles =64;
public static IEnumerable<IEnumerable<T>> DivideIntoChunks<T>(IEnumerable<T> iEnumerable )
{
  return iEnumerable
  .Select((x, i) => new { Index = i, Value = x })
  .GroupBy(x => x.Index / MaxHandles)
  .Select(x1 => x1.Select(x2 => x2.Value))
  ;
}

To jeszcze zamieszczę testy:
[TestCase(1, 1, 1)]
[TestCase(64, 1, 64)]
[TestCase(65, 2, 64)]
[TestCase(128, 2, 64)]
[TestCase(129, 3, 64)]
[TestCase(0, 0, 0)]
public void It_should_divide_into_chunks(int listNumber, int numberOfChunks, int firstChunkCount)
{
 var list = Enumerable.Repeat(1, listNumber);
 var listOfChunks = Generator.DivideIntoChunks(list);
 Assert.AreEqual(numberOfChuncks, listOfChunks.Count());
 Assert.AreEqual(firstChunkCount, listOfChunks.First().Count());
 Assert.AreEqual(listNumber, listOfChunks.SelectMany(x => x).Count());
}




niedziela, 13 stycznia 2013

Czyszczenie kolejek MSMQ w PowerShell

Parę razy musiałem wyczyścić kolejki w MSQM. Standardowe ręcznie usuwanie i tworzenie kolejkę jest bardzo pracochłonne. Po paru takich powtórzonych czynnościach, postanowiłem napisać skrypt w PS. Skrypt wykorzystuje bibliotekę System.Messaging.


[Reflection.Assembly]::LoadWithPartialName("System.Messaging")

$michineName = $env:COMPUTERNAME

$queueNames =  [System.Messaging.MessageQueue]::GetPrivateQueuesByMachine($michineName) | 
% {".\" + $_.QueueName} 

$queueNames  = $queueNames  |  
?{ $_ -like "*my.special*"}

$queueNames | 
foreach {
 [System.Messaging.MessageQueue]::Delete($_);
 [System.Messaging.MessageQueue]::Create($_, [bool]1) ;
 }

Krótki opis co robi skrypt:
1. Ładuje referencje do biblioteki Messaging
2. Pobiera nazwę komputera
3. Pobiera listę prywatnych kolejek i zwraca ich nazwy
4. Wybiera kolejki mające w nazwie "my.special"
5. Iteruje po wszystkich znalezionych kolejkach
6. Usuwa kolejkę
7. Tworzy transakcyjną kolejkę

Próbowałem zmienić proces usuwania i dodawania tej samej kolejki na pojedynczy proces czyszczenia kolejki, ale natrafiałem na pewne ograniczenia :/ Nie miałem wystarczającej ilości czasu, aby zamienić ten skrypt. Gdybyś znal inne sposoby na czyszczenie kolejek MSMQ to napisz w komentarzu.