2017-08-10 4 views
5

私はそうのような方法があります:"未割り当てのローカル変数の使用"エラーを抑制しますか?

public static long? FromIpv4ToLong(this string ipAddress) 
{ 
    var octets = ipAddress.Split(IpSplitChar); 
    if (octets.Length != 4) return null; 

    var success = long.TryParse(octets[0], out long a) 
        && long.TryParse(octets[1], out long b) 
        && long.TryParse(octets[2], out long c) 
        && long.TryParse(octets[3], out long d); 

    if (!success) return null; 

    return ((16777216L * a) + (65536L * b) + (256L * c) + d); 
} 

...今、変数abc、およびdは、彼らが参照されますポイントで「未割り当て」になることはありませんが、コンパイラはdoesnのをそのように見ることはできません。コンパイラに「とにかくそれを構築する」ように強制する方法はありますか?これらの値を事前に初期化するのは愚かなようです。

+4

、これは無効IP4アドレスを受け付けます。 – Lee

+0

私はオンライン広告交換の仕事をしています。 1秒あたり60〜100KのIPアドレスを処理しています.2桁のミリ秒の遅延SLAがあります。 'IPAddress.TryParse'は顕著な待ち時間を追加します。したがって、動詞です。私たちは、この種のものに対して、最も簡単で、最速で、最も効率的なアルゴリズムしか使用できません。 –

答えて

12

だけifボディ、コンパイラはすべてが確実に割り当てられていることを知っていないという事実を利用して、混乱を招くものだ無意味なローカル変数を避けるために、コードをリファクタリング:

public static long? FromIpv4ToLong(this string ipAddress) 
{ 
    var octets = ipAddress.Split(IpSplitChar); 
    if (octets.Length != 4) return null; 

    if (long.TryParse(octets[0], out long a) 
     && long.TryParse(octets[1], out long b) 
     && long.TryParse(octets[2], out long c) 
     && long.TryParse(octets[3], out long d) 
    { 
     return (16777216L * a) + (65536L * b) + (256L * c) + d; 
    } 

    return null; 
} 

または使用条件演算子(と簡単にするためにシフト使用):

public static long? FromIpv4ToLong(this string ipAddress) 
{ 
    var octets = ipAddress.Split(IpSplitChar); 
    return octets.Length == 4 
     && long.TryParse(octets[0], out long a) 
     && long.TryParse(octets[1], out long b) 
     && long.TryParse(octets[2], out long c) 
     && long.TryParse(octets[3], out long d) 
     ? (a << 24) | (b << 16) + (c << 8) | d 
     : null; 
} 
+0

私は、コンパイラがこれを理解できるのは興味深いと思いますが、他のコンパイラは理解できません。洞察に感謝します。 –

+2

@ JeremyHolovacs:元のコードを動作させるためには、コンパイラは 'success'変数の値に重要性を付ける必要があります。 「XとYの両方が実行されている場合、XとYに割り当てられた変数はすべて確実に割り当てられたものとして扱われるべきです」という点では、コードフローの理解と大きな違いがあります。 –

+0

時々私は、コンパイラが自分の意図を唱えることによって迷惑をかけることがあります。 –

1

代わりにこのような何かを試してみてください:

public static long? FromIpv4ToLong(this string ipAddress) 
{ 
    var octets = ipAddress.Split(IpSplitChar); 
    if (octets.Length != 4) return null; 

    if (long.TryParse(octets[0], out long a) 
       && long.TryParse(octets[1], out long b) 
       && long.TryParse(octets[2], out long c) 
       && long.TryParse(octets[3], out long d)){ 
     return ((16777216L * a) + (65536L * b) + (256L * c) + d); 
    } 

    return null; 
} 

コンパイラは、成功したときに実現するほどスマートではありません。

3

いいえ、コンパイル時エラーまたはコンパイル時エラーを無視する方法はありません。 は、初期化されていないローカル変数が読み込まれていないことをコンパイラが証明できることを保証する必要があります。幸い

、コンパイラは何も初期化されていない変数が今まで読んされていないことを証明することができるようにコードを再構築することは難しいことではありません:あなたは `IPAddress.TryParse`を使用することを検討すべきである

public static long? FromIpv4ToLong(this string ipAddress) 
{ 
    var octets = ipAddress.Split(' '); 
    if (octets.Length != 4) return null; 

    if (long.TryParse(octets[0], out long a) 
        && long.TryParse(octets[1], out long b) 
        && long.TryParse(octets[2], out long c) 
        && long.TryParse(octets[3], out long d)) 
    { 
     return ((16777216L * a) + (65536L * b) + (256L * c) + d); 
    } 

    return null; 
} 
関連する問題