C# と VB.NET の質問掲示板

わんくま同盟

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

ツリー一括表示

メソッド内の一部のみ派生したクラスに変えたい /tro (19/09/05(Thu) 10:23) #92246
Re[1]: メソッド内の一部のみ派生したクラスに変えたい /魔界の仮面弁士 (19/09/05(Thu) 10:48) #92250
Re[1]: メソッド内の一部のみ派生したクラスに変えたい /とっちゃん (19/09/05(Thu) 10:37) #92247
  └ Re[2]: メソッド内の一部のみ派生したクラスに変えたい /とっちゃん (19/09/05(Thu) 10:37) #92248
    └ Re[3]: メソッド内の一部のみ派生したクラスに変えたい /tro (19/09/05(Thu) 11:24) #92252
      └ Re[4]: メソッド内の一部のみ派生したクラスに変えたい /魔界の仮面弁士 (19/09/05(Thu) 11:50) #92254
        └ Re[5]: メソッド内の一部のみ派生したクラスに変えたい /tro (19/09/05(Thu) 12:31) #92255 解決済み


親記事 / ▼[ 92250 ] ▼[ 92247 ]
■92246 / 親階層)  メソッド内の一部のみ派生したクラスに変えたい
□投稿者/ tro (27回)-(2019/09/05(Thu) 10:23:00)

分類:[.NET 全般] 

2019/09/05(Thu) 10:24:48 編集(投稿者)
2019/09/05(Thu) 10:24:07 編集(投稿者)

基底クラスを使用するメソッド、派生クラスを使用するメソッドがそれぞれあるのですが、
メソッドの処理内容がクラスの型以外共通でしたので、
メソッドも一つに統一したいのですがいい方法はありますでしょうか。


・基底クラス
public class TestBase
{
 string ValueCommon {get; set;}
}

・派生クラス
public class TestA : TestBase
{
 string ValueA {get; set;}
}


・基底クラスを使用するメソッド
public virtual void Func()
{
 TestBase testBase = new TestBase
 {
  ValueCommon = "Test";
 }
}

・派生クラスを使用するメソッド
public override void Func()
{
 TestA testA = new TestA
 {
  ValueCommon = "Test";
 }
}

[ □ Tree ] 返信 編集キー/

▲[ 92246 ] / 返信無し
■92250 / 1階層)  Re[1]: メソッド内の一部のみ派生したクラスに変えたい
□投稿者/ 魔界の仮面弁士 (2357回)-(2019/09/05(Thu) 10:48:54)
No92246 (tro さん) に返信
> 基底クラスを使用するメソッド、派生クラスを使用するメソッドがそれぞれあるのですが、
提示のクラスには、公開されたメンバーが何も無いような…。
ValueCommon プロパティも ValueA プロパティも private スコープですよね?

やりたい事以前に、元のコードがそもそも文法的に間違っているような気がします。


> メソッドの処理内容がクラスの型以外共通でしたので、
virtual void Func() と override void Func() は、
TestBase / TestA に実装されているのでしょうか。
それとも、別のクラスに実装されているのでしょうか。


> TestBase testBase = new TestBase
> {
>  ValueCommon = "Test";
> }
セミコロンは「"Test"」の後ではなく、「}」に後に置くべきかと。


> メソッドも一つに統一したいのですがいい方法はありますでしょうか。
目的を正しく理解できているか自信が無いですが、
ValueCommon 自体は基底側に持つ実装なので、
 「TestBase x = new TestBase { ValueCommon = "Test" };」
 「TestA x = new TestA { ValueCommon = "Test" };」
ではなく、
 「TestBase x = new T { ValueCommon = "Test" };」
にすれば、T の部分を置き換えるだけで済む気がします。

T の指定を型パラメータで補うのか、Factory とするのかは状況次第。
[ 親 92246 / □ Tree ] 返信 編集キー/

▲[ 92246 ] / ▼[ 92248 ]
■92247 / 1階層)  Re[1]: メソッド内の一部のみ派生したクラスに変えたい
□投稿者/ とっちゃん (629回)-(2019/09/05(Thu) 10:37:06)
No92246 (tro さん) に返信
> 基底クラスを使用するメソッド、派生クラスを使用するメソッドがそれぞれあるのですが、
> メソッドの処理内容がクラスの型以外共通でしたので、
> メソッドも一つに統一したいのですがいい方法はありますでしょうか。
>
> ・基底クラスを使用するメソッド
> public virtual void Func()
> {
>  TestBase testBase = new TestBase
>  {
>   ValueCommon = "Test";
>  }
> }
>
> ・派生クラスを使用するメソッド
> public override void Func()
> {
>  TestA testA = new TestA
>  {
>   ValueCommon = "Test";
>  }
> }
>
この2種類の Func() は外的にはどういう風に区別される想定なのでしょうか?

一つに統一というのは、内部的にフラグなどで切り分けたいということでしょうか?

例えば、こんな感じ。

public void Func()
{
TestBase obj = null;
if( IsUseTestA ) obj = new TestA;
else obj = new TestBase;
obj.ValueCommon = "Test";
}

オブジェクトの生成を外に出して、こんな感じにする方法もあります。

public void Func( TestBase obj )
{
obj.ValueCommon = "Test";
// 実際の処理
}

どっちにしても見えてる部分だけじゃ何がしたいのかがわからないので、
具体的にどういう形にするのがいいか?がわかりません。

[ 親 92246 / □ Tree ] 返信 編集キー/

▲[ 92247 ] / ▼[ 92252 ]
■92248 / 2階層)  Re[2]: メソッド内の一部のみ派生したクラスに変えたい
□投稿者/ とっちゃん (630回)-(2019/09/05(Thu) 10:37:40)
あ、図表モードにしてなかった。。。orz

[ 親 92246 / □ Tree ] 返信 編集キー/

▲[ 92248 ] / ▼[ 92254 ]
■92252 / 3階層)  Re[3]: メソッド内の一部のみ派生したクラスに変えたい
□投稿者/ tro (28回)-(2019/09/05(Thu) 11:24:43)
2019/09/05(Thu) 11:27:00 編集(投稿者)
2019/09/05(Thu) 11:26:07 編集(投稿者)

<pre><pre>返信ありがとうございます。

>この2種類の Func() は外的にはどういう風に区別される想定なのでしょうか?
基底クラスを使用するFunc()はアプリA、派生クラスを使用するFunc()はアプリBで使用するという形になっています。
基底クラス、及び基底クラスを使用するFunc()はアプリA、Bの共通dllに存在します。

>一つに統一というのは、内部的にフラグなどで切り分けたいということでしょうか?
従って共通のdllからは派生先のクラスは使用できませんので、フラグでの切り分けはできません。

ソースコードの文法ミスがあり申し訳ございません。
改めて書き直しました。

・基底クラス(アプリA、B共通、実際にはアプリAのみ使用)
public class TestBase
{
public string ValueCommon {get; set;}
}

・派生クラス(アプリBのみ)
public class TestA : TestBase
{
public string ValueA {get; set;}
}


・基底クラスを使用するメソッド(アプリA、B共通、実際にはアプリAのみ使用)
public virtual void Func()
{
TestBase testBase = new TestBase
{
ValueCommon = "Test"
};
}

・派生クラスを使用するメソッド(アプリBのみ)
public override void Func()
{
TestA testA = new TestA
{
ValueCommon = "Test"
};
}</pre></pre>
[ 親 92246 / □ Tree ] 返信 編集キー/

▲[ 92252 ] / ▼[ 92255 ]
■92254 / 4階層)  Re[4]: メソッド内の一部のみ派生したクラスに変えたい
□投稿者/ 魔界の仮面弁士 (2359回)-(2019/09/05(Thu) 11:50:03)
No92252 (tro さん) に返信
> 基底クラスを使用するFunc()はアプリA、派生クラスを使用するFunc()はアプリBで使用するという形になっています。
> 基底クラス、及び基底クラスを使用するFunc()はアプリA、Bの共通dllに存在します。

「virtual void Func()」は、TestBase 上に実装されているのでしょうか。
それとも別のクラスで定義しているのでしょうか。

「アプリA で使用する、共通dll 内の Func()」は何処に実装されているのでしょう。
TestA でしょうか。あるいは、それらとは別のクラス内に実装されているのでしょうか。


> public virtual void Func()
> {
>  TestBase testBase = new TestBase
>  {
>   ValueCommon = "Test"
>  };
> }
> public override void Func()
> {
>  TestA testA = new TestA
>  {
>   ValueCommon = "Test"
>  };
> }

インスタンスをセットしているのは、フィールド変数ではなく、ローカル変数なのですよね?
スコープ的に、インスタンスを生成してすぐ破棄されているだけなので、
メソッドの意図が良く分からないです…。

ひとまず、Func をオーバーライドすること無く、同じような動作にしたいという話なら、たとえば

// --- 基底実装 ---
 protected virtual TestBase Create() => new TestBase();
 public /* virtual */ void Func()
 {
  TestBase x = Create();
  x.ValueCommon = "Test";
 }

// --- 派生実装 ---
 protected override TestBase Create() => new TestA();
 // Func() はもとの実装のままで OK

のように書けます。
[ 親 92246 / □ Tree ] 返信 編集キー/

▲[ 92254 ] / 返信無し
■92255 / 5階層)  Re[5]: メソッド内の一部のみ派生したクラスに変えたい
□投稿者/ tro (29回)-(2019/09/05(Thu) 12:31:42)
No92254 (魔界の仮面弁士 さん) に返信
> 「virtual void Func()」は、TestBase 上に実装されているのでしょうか。
> それとも別のクラスで定義しているのでしょうか。

はい、別のクラスに定義しています。

> 「アプリA で使用する、共通dll 内の Func()」は何処に実装されているのでしょう。
> TestA でしょうか。あるいは、それらとは別のクラス内に実装されているのでしょうか。

こちらも共通dllの別のクラスになります。


> インスタンスをセットしているのは、フィールド変数ではなく、ローカル変数なのですよね?
> スコープ的に、インスタンスを生成してすぐ破棄されているだけなので、
> メソッドの意図が良く分からないです…。

ローカル変数であっています。


> ひとまず、Func をオーバーライドすること無く、同じような動作にしたいという話なら、たとえば
>
> // --- 基底実装 ---
>  protected virtual TestBase Create() => new TestBase();
>  public /* virtual */ void Func()
>  {
>   TestBase x = Create();
>   x.ValueCommon = "Test";
>  }
>
> // --- 派生実装 ---
>  protected override TestBase Create() => new TestA();
>  // Func() はもとの実装のままで OK
>
> のように書けます。

なるほど、ありがとうございます。
解決済み
[ 親 92246 / □ Tree ] 返信 編集キー/


管理者用

- Child Tree -