2011-01-02 18 views
9

Biorąc trochę kodu:Jak zezwolić na niejawną konwersję?

class Json 
{ 
} 

class Program 
{ 
    static void Main(string[] args) 
    { 
    } 

    Json MyAction() 
    { 
     return "{\"json\": 1}"; 
    } 
} 

czy jest coś mogę dodać do klasy Json aby to skompilować? Coś, co pozwala kompilatorowi wiedzieć, że może niejawnie rzucić strunę do Jsona?

+1

bym dodać '.ToJson()' metodę rozszerzenia zamiast przeciążenia operatora 'implicit' ponieważ tego rodzaju niejawna konwersja jest niezgodny kilka ważnych wskazówek (patrz odpowiedź na Saeed). W szczególności może rzutować, nie jest bezstratny i ma dziwną semantykę w porównaniach. – CodesInChaos

+0

@CodeInChaos: Mogę sprawić, żeby nie było rzucać :) Moim największym zmartwieniem jest to, że akcja po prostu zwraca inny typ, aby odróżnić go od ciągu, nawet jeśli w przeciwnym razie może działać idealnie jak ciąg. W ten sposób wiem, który ContentType ustawić, a użytkownik nie musi wykonywać dodatkowej pracy (wystarczy odpowiednio ustawić typ zwracanej funkcji). – mpen

Odpowiedz

27

Deklaracja implicit operator w C# pozwala na określenie:

{type to convert to} ({type to convert from} variablename) 

Oto prosty przykład:

class Json 
{ 
    private Json(string json) 
    { 
     //logic to parse string into object 
    } 

    public static implicit operator Json(string input) 
    { 
     return new Json(input); 
    } 
} 

Kilka uwag:

  • Pierwsze, I wouldn” t koniecznie jechać tą drogą, ponieważ większość str w aplikacji nie są semantycznie równoważne ciągowi JSON. Celem operatora konwersji jest powiedzenie, że dwa typy zawsze reprezentują semantycznie równoważną informację (lub wystarczająco blisko semantycznie równoważną, aby była ona użytecznie traktowana jako taka). Zamiast tego polecam zaimplementowanie metody static Json Parse(string input) lub nawet static bool TryParse(string input, out Json json) na twojej klasie Json. Callsite, ogólnie, powinien wiedzieć, czy spodziewa się, że własny ciąg będzie zawierał Json.

  • Zazwyczaj, jeśli moja klasa oferuje niejawną konwersję typu z typu, najlepiej jest wykonać dowolną logikę analizowania lub ctorowania dla tego samego typu: private. Gwarantuje to, że istnieje tylko jeden sposób, aby konsumenci wykonywali daną rzecz, nie na dwa sposoby (ctor i konwersja) - stąd prywatny ctor w powyższym przykładzie. Mogą istnieć wyjątki od tej reguły, ale była to dla mnie dobra ogólna zasada.

  • Niejawna konwersja pozwala również na kilka interesujących rzeczy z operatorami porównania. Na przykład teraz, gdy możesz niejawnie przekonwertować z ciągu znaków na json, możesz także wykonać: if(myJson == "blah") i wykona konwersję, a następnie wywoła operator == na obiekcie Json, który domyślnie dokona porównania równości odniesienia.

+0

Przyjmie w ciągu ~ 12 minut. Nie wiedziałem, że istnieje słowo kluczowe "implicit" dla tego typu rzeczy .. fajne :) – mpen

4

dodać operator implicit:

public static implicit operator Json(string s) 
{ 
    return new Json(s); 
} 

Domniemana kluczowe służy do deklarowania niejawnego operatora konwersji typu zdefiniowanego przez użytkownika. Użyj go, aby włączyć niejawne konwersje między typem zdefiniowanym przez użytkownika a innym typem, jeśli konwersja gwarantuje, że nie spowoduje utraty danych.

3

Można mieć niejawny konwerter ale dbać aby nie stracić danych:

Poprzez wyeliminowanie niepotrzebnych odlewane, konwersje niejawne mogą poprawić czytelność kodu źródłowego . Jednak , ponieważ niejawne konwersje mogą wystąpić bez podania przez programistę tych wartości, należy zachować ostrożność, aby zapobiec nieprzyjemnym niespodziankom.Ogólnie rzecz biorąc, niejawni operatorzy konwersji powinninieujmować wyjątków i nigdy nie tracić informacji o , aby można było ich bezpiecznie używać bez świadomości programisty . Jeśli operator konwersji nie może spełnić tych kryteriów, powinien być oznaczony jako jednoznacznie oznaczony jako .

zobaczyć MSDN

Powiązane problemy