Pokazywanie postów oznaczonych etykietą wishlist. Pokaż wszystkie posty
Pokazywanie postów oznaczonych etykietą wishlist. Pokaż wszystkie posty

czwartek, 20 listopada 2014

W końcu będzie null-conditional operator w C# 6

3 dni temu obejrzałem filmik z nowymi featuresami C#. Jest, w końcu, dziękuję. Wiem, że c# jest bardzo dynamicznie rozwijanym językiem, ale oczekiwałem ... może od kiedy zacząłem programować obiektowo, bezpiecznej nawiagacji po polach nie zważając na null'e. Odkąd ludzie wymyślili wartość nulla to nazwali tą wartość błędem wartym miliard dolarów. Już wcześniej operator bezpieczeń nawigacji był stosowany w innych językach. Słyszałem, że ma być null-conditional operator, ale myślałem, że ten operator promuje projekt Roslyn, więc nie wiedziałem czy ten operator będzie standardowo w C#.




A poniżej jest filmik z konferencji BUILD 2014:



A tutaj filmik z TechEd


Co prawda, w prezentacjach są te same przykłady kody, jakby nie mogli wymysleć innych zastosowań niż konwerter tablicy pointów do JSONa :)
Wydaje mi się, że w taki sposób próbują utrwalić wiedzę.

Jeszcze podoba mi się operator nameof. Wiem, że parę moich znajomych na ten operator czekało.

środa, 12 marca 2014

Pobieranie z GAC za pomocą PowerShell

Tak się zastanawiam, dlaczego PowerShell nie ma możliwości pobrania danych z GAC. PS wymaga zainstalowanego .NET, a najnowsze systemy z automatu mają ten framwork zainstalowany. Niestety jesteśmy zmuszeni do używania GacUtil.exe (Global Assembly Cache Tool). Napisałem skrypt do zwracania elementów z GACy.

function Get-GAC
{
    [CmdletBinding()]
    param()

& 'C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\gacutil.exe' /L |
? { $_ -match '^  ([\w\.]+,.*)$' } |
    % { 
        $fullName = ($Matches[1])
        try
        {
           $assembly = [System.Reflection.Assembly]::Load($fullName)
           $assembyName = $assembly.GetName()

           new-object PSObject -prop @{ 
                FullName = $assembly.FullName; 
                GAC = $assembly.GlobalAssemblyCache;
                Version = $assembly.ImageRuntimeVersion;
                FullyTrusted = $assembly.IsFullyTrusted;
                Location = $assembly.Location;
                Name = $assembyName.name;
                ReferencedAssemblie = $assembly.GetReferencedAssemblies();
                Token = ($assembyName.GetPublicKeyToken() |  foreach {$_.ToString("X2")}) -join '';
                HashAlgorithm = $assembyName.HashAlgorithm;
                CultureInfo = $assembyName.CultureInfo;
           }
        }
        catch [system.exception]
        {
            Write-Verbose $_
        }
    }| sort Name -unique 
}

Przykład użycia jest poniżej. Dodatkowo dodajemy parametr verbose, gdyż nie wszystkie biblioteczki są załadowywane. Jeszcze troszkę będę musiał przy tym posiedzieć i sprawdzić dlaczego nie wszystko zostaje załadowane. Może ty masz jakiś pomysł??
( Get-GAC -Verbose ) | out-gridview

niedziela, 2 lutego 2014

Skrypt w parametrach domyślnych w PS

Jak piszę kod w C# i mam metodę z możliwością ustawienia domyślnych parametrów to staram się użyć domyślnych parametrów (jednak, nie polecam robienia czegoś takiego dla interfejsów). Czasami problem pojawia się, kiedy do parametru chciałbym przypisać wartość z innej metody. Składnia języka C# na to nie pozwala:


Domyślne parametry mają pewne ograniczenia m.in.:
- nie mogą posiadać modyfikatora ref, out, czy params
- muszą być stałymi w czasie kompilacji
- nie mogą być metodami, właściwościami ani wyrażeniem
- domyślne parametry muszą być definiowane po wymaganych parametrach w metodzie

Co mi się bardzo podoba w PowerShellu to możliwość wywoływania polecenia razem z domyślnymi wartości ( mogą to być bloki skryptów).
PS jest dużo bardziej elastyczny językiem programowania i możemy wprowadzić wymóg wprowadzenia parametru user oraz podania hasła, które na ekranie będzie 'ukryte' :)
function Do-SomeThing
{
    param(
    [string] $computerName = $env:computerName,
    [string] $user =  $(throw "Argument user is not set"),
    [string] $passwd =  $(Get-Password)
    )
    Write-Host "user:$user passwd:$passwd on computer:$computerName"
} 

Przy wywołaniu prostego polecenia dostajemy błąd:
PS>Do-SomeThing 
Argument user is not set

Kiedy wywołamy polecenie z użytkownikiem to dostajemy okienko z możliwością wpisania hasła


Możesz wywołać funkcję z hasłem i nazwą komputera:
Do-SomeThing -user "Arek" -passwd "Abc" -computerName "MyPc"

No i jeszcze funkcja do pobierania hasła:
function Get-Password
{
    $securePass = Read-Host "Enter Password" -AsSecureString
    $bstr = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($securePass)
    $pass = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($bstr)
    [System.Runtime.InteropServices.Marshal]::ZeroFreeBSTR($bstr)
    return $pass
}
Oczywiście w niektórych przypadkach można użyć Parameter(Mandatory) oraz walidatorów (ValidateScript), ale chciałem Ci przedstawić co można zrobić z domyślnymi parametrami.

sobota, 26 października 2013

Statyczne analizy kodu w czasie

Tak się zastanawiam, co by było gdybyśmy wiedzieli jak z biegiem czasu zmieniały się nazwy klas, metod, słowa-klucze używane w naszych projektach. Co jakiś czas kod źródłowy byłby skanowany i informacje byłyby zapisywane do bazy. Z tego można by było przedstawić jaka klasa z biegiem czasu/releasów jest najbardziej popularna, czy nazwy obiektów są zależne od nazwy klas, ile jest komentarzy, jakie jest kodowanie tekstów itp. Mamy narzędzia, aby dokonać statycznej analizy kodu, ale jeszcze nie ma możliwości analizy tych wyników dla okresów czasowych.

Taki pomysł przyszedł mi do głowy przy oglądaniu prezentacji o n-gram. Bardzo zapraszam do obejrzenia:



wtorek, 19 marca 2013

Z Func do IEqualityComparer

Brakuje mi jednej klasy w BCL, która mogła by stworzyć obiekt implementujący IEqualityComparer z wyrażenia lambda . Ten temat był już wałkowany, ale pomimo tego napiszę czego mi brakuje i jakie jest zastosowanie.

Mamy klasę:
public class Value
{
    public int IntValue { get; set; }
    public string StringValue { get; set; }
    public override string ToString()
    {
        return IntValue + "_" + StringValue;
    }
}

Tworzymy comperer (klasa porównująca dwa obiekty), w którym podajemy funkcję zwracającą informację po jakim będziemy porównywać obiekty. Ta funkcja będzie nam potrzebne do tworzenia hash kodu.
public class KeyEqualityComparer<T> : IEqualityComparer<T>
{
    public Func<T, object> _keyToCompar { get; private set; }

    public KeyEqualityComparer(Func<T, object> keyToCompar)
    {
        _keyToCompar = keyToCompar;
    }

    public bool Equals(T x, T y)
    {
        return _keyToCompar(x).Equals(_keyToCompar(y));
    }

    public int GetHashCode(T obj)
    {
        return _keyToCompar(obj).GetHashCode();
    }
}

Aby przedstawić KeyEqualityComparer wystarczy wywołać następujący kod:
var list = new List<Value>
{
    new Value {IntValue = 1, StringValue = "One "},
    new Value {IntValue = 1, StringValue = "Two"}
};

var distinctList1 = list.Distinct(new KeyEqualityComparer<Value>(x =>x.IntValue));

Dodatkowo możemy stworzyć extension method:
public static IEqualityComparer<T> ToEqualityComparer<T>(this  Func<T, object> func)
{
    KeyEqualityComparer<T> equalityComparer = new KeyEqualityComparer<T>(func);
    return equalityComparer;
}

I wtedy możemy operować za pomocą wyrażeniu lambda:
Func<Value, object> keyToCompare = x => x.IntValue;
var distinctList = list.Distinct(keyToCompare.ToEqualityComparer());


wtorek, 19 czerwca 2012

Czy goto ma zastosowanie w c#

Goto to zło. Ale w niektórych sytuacjach przydaje się.



Aby zobrazować dobre wykorzystanie goto przedstawię ci kod. 2 razy iterujemy po macierzy. Jeżeli znajdziemy element, który ma wartość 0 to kończymy tą podwójną pętle. Do tego będziemy potrzebować przerwania pierwszej pętli oraz zmienną informującą o tym czy zostało dokonane przerwanie. Przydałaby się instrukcja doublebreak, która mogłaby zakończyć dwie pętle :/

            int[,] ints = new int[2, 2];
            for (int i = 0; i < 2; i++)
            {
                bool breakSet = false;
                for (int j = 0; j < 2; j++)
                {
                    if (ints[0, 0] == 0) //check if is zero
                    {
                        breakSet = true;
                        break;
                    }
                }
                if (breakSet)
                {
                    break;
                }
            }


Ok, kod jest prosty. Dajmy na to, że zamiast 2 pętli for mamy 4 pętle for.
int oneDimSize = 2;
int[, , ,] ints = new int[oneDimSize, 
oneDimSize,
oneDimSize,
oneDimSize];

bool breakSetForI = false;
for (int i = 0; i < oneDimSize; i++)
{
    bool breakSetForJ = false;
    for (int j = 0; j < oneDimSize; j++)
    {
        bool breakSetForK = false;
        for (int k = 0; k < oneDimSize; k++)
        {
            bool breakSetForL = false;
            for (int l = 0; l < oneDimSize; l++)
            {
                if (ints[i, j, k, l] == 0)
                {
                    breakSetForL = true;
                    break;
                }
            }
            if (breakSetForL)
            {
                breakSetForK = true;
                break;
            }
        }
        if (breakSetForK)
        {
            breakSetForJ = true;
            break;
        }

    }
    if (breakSetForJ)
    {
        breakSetForI = true;
        break;
    }
}

Tutaj już duplikujemy instrukcje if i musimy skorzystać z 4 zmiennych. To samo za pomocą goto wygląda następująco:
int oneDimSize = 2;
int[, , ,] ints = new int[oneDimSize,
 oneDimSize,
 oneDimSize,
 oneDimSize];

bool breakSet = false;
for (int i = 0; i < oneDimSize; i++)
{
    for (int j = 0; j < oneDimSize; j++)
    {
        for (int k = 0; k < oneDimSize; k++)
        {
            for (int l = 0; l < oneDimSize; l++)
            {
                if (ints[i, j, k, l] == 0)
                {
                    goto LabelIsZero;
                }
            }
        }
    }
}
return;

LabelIsZero:
breakSet = true;

Kod z zastosowaniem goto jest zdecydowanie czytelniejszy. Gdybyś miał jakiś inny pomysł na dobre zastosowanie goto to daj znać.