1

データを必要とするクラスがあります。これは、バイトまたはファイルパスとして指定できます。

現時点では、ファイルをバイト配列に読み取ってから、クラスをセットアップします。また、別のセパレーターでは、パラメーターとして渡されたバイトから直接クラスを設定します。

最初のコンストラクター (ファイル パス) で 2 番目のコンストラクター (バイト) を呼び出すには、次のようにします。

    public DImage(byte[] filebytes) : this()
    {
        MemoryStream filestream = null;
        BinaryReader binReader = null;
        if (filebytes != null && filebytes.Length > 0)
        {
            using (filestream = new MemoryStream(filebytes))
            {
                if (filestream != null && filestream.Length > 0 && filestream.CanSeek == true)
                {
                    //do stuff
                }
                else
                    throw new Exception(@"Couldn't read file from disk.");
            }
        }
        else
            throw new Exception(@"Couldn't read file from disk.");
    }


    public DImage(string strFileName) : this()
    {
        // make sure the file exists
        if (System.IO.File.Exists(strFileName) == true)
        {
            this.strFileName = strFileName;
            byte[] filebytes = null;
            // load the file as an array of bytes
            filebytes = System.IO.File.ReadAllBytes(this.strFileName);
            //somehow call the other constructor like
            DImage(filebytes);                         
        }
        else
           throw new Exception(@"Couldn't find file '" + strFileName);

    }

では、最初のコンストラクターを (コードのコピーと貼り付けを節約するために) 2 番目のコンストラクターから呼び出すにはどうすればよいでしょうか?

4

3 に答える 3

4

実際には、2つの静的メソッドを公開することをお勧めします。

public static DImage FromFile(string filename)
{
    // Load image, then call constructor
}

public static DImage FromData(byte[] data)
{
    // Do anything you need to, then call the constructor
}

コンストラクターの正確な形式はあなた次第ですが、私はおそらくそれをプライベートにします。静的ファクトリメソッドを使用すると、私の経験ではコードがより明確になり、実際に作業を行う準備ができるまで、実際のコンストラクターの呼び出しを延期できることを意味します。これは、フィールドを読み取り専用にするなどの点で役立ちます。大きな欠点は、継承のサポートがないことです。

于 2013-02-11T14:38:42.630 に答える
4

たとえば、バイトを処理するために両方のコンストラクターによって呼び出されるbyte[]as パラメーターを取るプライベート メソッドを作成できます。ProcessImage(byte[] myparam)

補足: のstream代わりに を使用することを検討してくださいbyte[]


簡単な例:

public DImage(byte[] filebytes) : this()    // Remove if no parameterless constructor
{
    MemoryStream filestream = null;
    BinaryReader binReader = null;
    if (filebytes != null && filebytes.Length > 0)
    {
        using (filestream = new MemoryStream(filebytes))
        {
            this.ProcessStream(filestream);
        }
    }
    else
        throw new Exception(@"Couldn't read file from disk.");
}

public DImage(Stream stream) : this()   // Remove if no parameterless constructor
{
    this.ProcessStream(stream);
}    

public DImage(string strFileName) : this()  // Remove if no parameterless constructor
{
    // make sure the file exists
    if (System.IO.File.Exists(strFileName) == true)
    {
        this.strFileName = strFileName;

        // process stream from file
        this.ProcessStream(System.IO.File.Open(strFileName));
    }
    else
       throw new Exception(@"Couldn't find file '" + strFileName);
}

...

private ProcessStream(Stream myStream)
{
    if (filestream != null && filestream.Length > 0 && filestream.CanSeek == true)
    {
        //do stuff
    }
    else
        throw new Exception(@"Couldn't read file from disk.");
}
于 2013-02-11T14:35:03.243 に答える
0

3 つのコンストラクターの実装を想像できます。

  1. System.Streamからアクセスできるを受け入れるSystem.IO.StreamReader
  2. バイト配列を受け取り、それを にラップしてSystem.IO.MemoryStream、最初のコンストラクターを呼び出します。
  3. ファイル名を受け取り、 を使用してロードしSystem.IO.FileStream、最初のコンストラクターを呼び出します。

次に例を示します。

using System.IO;

// ...

public DImage(Stream Stream)
{
    using (var reader = new StreamReader(Stream))
    {
        // Read the image.
    }
}

public DImage(byte[] Bytes) 
    : this(new MemoryStream(Bytes))
{
}

public DImage(string FileName) 
    : this(new FileStream(FileName, FileMode.Open, FileAccess.Read))
{
}

これにより、例外の処理も容易になります。System.IO.FileNotFoundExceptionファイルが存在しない場合、FileStream のコンストラクターは をスローするため、-class をインスタンス化している場所ならどこからでも処理できますDImage

try
{
    var image = new DImage(@"C:\Test.img");
}
catch (System.IO.FileNotFoundException e)
{
    // The image could not be found.
}
catch (Exception e)
{
    // Something else happened.
}

このメソッドは、thisコンストラクターの背後にあるキーワードを使用して、特別な構築ケースを既定のコンストラクターに委譲します。これには 2 つの利点があります。

  1. コードの重複を削除して、必要なコードを減らします。
  2. デフォルトのコンストラクターを定義し、System.Stream. クライアントは、コンストラクターを呼び出してメモリ チャンクまたはファイル システム エントリからイメージを読み込むか、独自のストリームを実装してカスタム データソース (DB BLOB、NetworkStreams など) を提供できます。
于 2013-02-11T14:50:43.293 に答える