2016-10-06 17 views
2

Ich habe einige duplizierte Code, aber nicht sicher, die beste Möglichkeit, es zu vereinfachen.Kann dies in C# vereinfacht werden?

private void CheckData(long PKID, int ExpectedResult, string Server) 
{ 
    var a = _ARepo.GetAll(); 
    var b = _BRepo.GetAll(); 

    if(Server == "A") 
    { 
     a.Find(x => x.PKID == PKID).Result.ShouldBe(ExpectedResultId); 
    } 

    if (Server == "B") 
    { 
     b.Find(x => x.PKID == PKID).Result.ShouldBe(ExpectedResultId); 
    } 
} 

Dies ist ein Testprojekt Einheit und ich bin mit der Shouldly Bibliothek. Irgendwelche Ideen geschätzt.

+3

Was die Arten von 'a' sind und 'b'? –

+0

(Server == "A"? A: b) .Find (...) nehme ich an. Oder führen Sie einfach eine Variable ein und weisen Sie ihr je nach Server entweder a oder b zu. Dann Abfrage für diese Variable abfragen. – Evk

+0

@GiladGreen Sie sind vom gleichen Typ, der das Repository-Muster mit 'Dapper' verwendet, um Daten von einer SQL Server-Datenbank abzurufen. –

Antwort

6
private void CheckData(long PKID, int ExpectedResult, string Server) 
{ 
    //Setting to empty because I don't know what happens if it is not "A" nor "B" 
    IEnumerable<YourType> data = Enumerable.Empty<YourType>(); 

    if(Server == "A") 
     data = _ARepo.GetAll(); 
    else if(Server == "B") 
     data = _BRepo.GetAll(); 

    data.Find(Find(x => x.PKID == PKID).Result.ShouldBe(expectedId); 
} 

Wenn der Server Wert nur sein kann A oder B dann können Sie mit einem if else oder besser ersetzen noch ein ?: Operator Dann wird es wie folgt aussehen:

var data = Server == "A" ? _ARepo.GetAll() : _BRepo.GetAll(); 
data.Find(Find(x => x.PKID == PKID).Result.ShouldBe(expectedId); 

In dem Fall, dass beide Repo s implementieren die gleiche Schnittstelle ein besseres Design wird die IRepo als Parameter der Funktion zu erhalten. Auf diese Weise hat die Funktion nur eine Rolle - das heißt, Daten zu prüfen (und nicht auch zu entscheiden, welche Daten zu prüfen sind)

+1

Sehr hilfreich, habe ich die Methode nach Ihrem Vorschlag auf 'private void CheckData (lange PKID, int ExpectedResult, Repository Repo)' –

+0

@MarkAllison - Froh, zu helfen :) BTW - wenn bereits Writing UT und bessere Verantwortlichkeiten der Codesegmente dann Ich würde empfehlen, ein 'IRepository' anstelle eines konkreten' Repository' zu haben. Check out [SOLID] (https://en.wikipedia.org/wiki/SOLID_ (object-oriented_design)) - Es ist eine Art von Unterschied zwischen dem Schreiben von Code zum Erstellen von Kunst :) –

3

Sie können eine Hilfsmethode machen mit dieser Doppelarbeit beschäftigen:

private void CheckFind<T>(List<T> a, int expectedId) where T : IWithId { 
    a.Find(x => x.PKID == PKID).Result.ShouldBe(expectedId); 
} 

Rufen Sie diese Methode zweimal aus CheckData:

if(Server == "A") { 
    CheckFind(_ARepo.GetAll(), ExpectedResultId); 
} 
if(Server == "B") { 
    CheckFind(_BRepo.GetAll(), ExpectedResultId); 
} 
+0

@Evk True. Die Zuweisung einer einzelnen Variablen erfordert jedoch, dass beide Typen gleich sind, während meine Vorgehensweise leicht an Listen generischen Typs mit einer Schnittstelle zum Abrufen einer ID angepasst werden kann. – dasblinkenlight

+0

@Servy Das wäre wahr, wenn Sie 'IEnumerable ' verwenden könnten. Die Verwendung von 'Find' legt jedoch nahe, dass OP' List 'verwendet, also würde Ihr Trick nicht funktionieren. – dasblinkenlight

+0

@Servy Bitte beachten Sie die Änderung. – dasblinkenlight

1

ja, wenn Sie Ihren Code Code Refactoring und Ihre _ARepo.GeAll machen können und _BRepo.getAll implementiert die gleiche Schnittstelle in den zurückgegebenen Typ wird dies etwa so aussehen:

private void CheckData(long PKID, int ExpectedResult, string Server, IRepo repo) 
{ 
    var b = repo.GetAll(); 
    b.Find(x => x.PKID == PKID).Result.ShouldBe(ExpectedResultId); 
} 
1

Mit einigen kurzen if Notation können Sie die folgenden Nehmen Sie die folgenden, dass _ARepo und _BRepo die gleiche ist aus der gleichen Klasse, aber unterschiedliche Verbindungszeichen

private void CheckData(long PKID, int ExpectedResult, string Server) 
{ 
    BaseType repo = Server == "A" ? _ARepo : _BRepo; 
    repo.GetAll().Find(x => x.PKID == PKID).Result.ShouldBe(ExpectedResultId); 
} 

Unter der Annahme, dass sie nicht die gleiche Basetype sind aber das GetAll()

private void CheckData(long PKID, int ExpectedResult, string Server) 
{ 
    IEnumerable<YourType> repo = Server == "A" ? _ARepo.GetAll() : _BRepo.GetAll(); 
    repo.Find(x => x.PKID == PKID).Result.ShouldBe(ExpectedResultId); 
} 
+1

Sie können nicht die implizite var mit dem Conditional-Operator verwenden, wenn es keine implizite Konvertierung zwischen _ARepo und _BRepo –

+0

Dies ist, aber es ist ziemlich einfach zu ahnen, dass der _ (x) Repo ist derselbe "Typ", wenn Sie nur die Art und Weise betrachten, wie der Code strukturiert ist, und dass die Verbindungszeichenfolge nur für Server 'A' und Server 'B' unterschiedlich sein würde Es ist dasselbe und wenn es nicht das Gleiche ist –

1

IEnumerable Wenn alle Repos die gleiche Schnittstelle (wie IRepo) implementiert. Sie können eine Hilfsmethode wie dieser

private IRepo GetRepo(string server) 
    { 
     var repos = new Dictionary<string, IRepo> 
     { 
      { "A", _ARepo }, 
      { "B", _BRepo } 
     }; 

     return repos[server]; 
    } 

Die Verwendung sehr einfach erstellen

private void CheckData(long PKID, int ExpectedResultId, string Server) 
    { 
     var repo = GetRepo(Server); 
     repo.GetAll().Find(x => x.PKID == PKID).Result.ShouldBe(ExpectedResultId); 
    } 
Verwandte Themen