2016-04-15 2 views
2
public dynamic obj1(dynamic obj2) 
    { 
     if (obj2.GetType() == typeof(Obj3) 
      { 
      //do something 
      } 

     if (obj2.GetType() == typeof(Obj4) 
      { 
      //do something else 
      } 

     if (obj2.GetType() == typeof(Obj5) 
      { 
      //do something else 
      } 

      //return something 
    } 

これを改善する方法はありますか?私は約70種類のオブジェクトと比較するために反射を使用することはできません。これ以外にどのように改善できるかわかりません。動的オブジェクト、Ifステートメントで、この関数を改善する方法

この関数の呼び出し元は、右のタイプ(動的でない)に渡しされますが、それは、動的に返す方法私がある場合には、この1

+0

:機能が長い場合は、ラムダを使用することはありませんもちろん、それから、あなたはこのように宣言したいですifの配列。あなたの声明が真であるかどうかをチェックするならば、この方法であなたは何の手続きもしません。 これはselectステートメントでも行うことができます。 – codemonkeyliketab

+0

クラス自体(Obj-n)を変更することができる場合は、問題のコードブロックを含むメソッドを使用して、それらに共通のインターフェイスを配置します。 'dynamic'を使用しているので、C#は正しい実装にディスパッチします。 –

+0

@Frank Jあなたは何を意味するのですか?私はあまりにもあなたに従っていると確信していません –

答えて

4

ファーストクラスの関数で何かできますが、これはjavascriptのようなものでどうやって行うのでしょうか。

しかし、C#の場合でも、機能的アプローチは式典では低く、テスト可能であり、定型文のほとんどが削除されます。オブジェクト指向の選択肢は、意図にに関して海域だけで泥だらけに私には思える:ここ

はラムダと簡略化した例である:

using System; 
using System.Collections.Generic; 
class MainClass { 
    public static void Main (string[] args) { 

    var contents = new Dictionary<System.Type, Func<dynamic, string>> 
     { 
      {typeof(int), o => "is int"}, 
      {typeof(string), o => "is string"} 
     }; 

    Func<dynamic, string> worker = o => contents[o.GetType()](o); 

    Console.WriteLine(worker(1)); 
    Console.WriteLine(worker("foo")); 
    } 
} 

あなたがここでそれを実行することができます。 https://repl.it/CGJO/4

あなたが置きます処理したいすべてのタイプの辞書の関数。 obj2の場合にのみ/ elseifsの代わりに、1型使用のものとすることができるので

Func<dynamic, string> intFunc = delegate(dynamic o) 
    { return "Is integer";}; 
Func<dynamic, string> stringFunc = delegate(dynamic o) 
    { return "Is string";}; 

var contents = new Dictionary<System.Type, Func<dynamic, string>> 
    { 
     {typeof(int), intFunc}, {typeof(string), stringFunc} 
    }; 

https://repl.it/CGJO/8

+0

var contents = new Dictionary > { {typeof(int)、o => RunFuctionA();}、 };どうすればこのようなことができますか? –

1

で始めるために、私はレリ知りませんこれを改善できますか?

各タイプのオーバーロードを作成します。コードの量は、70の異なるif文とは大きく異なり、コンパイル時の型の安全性があります。

それぞれのコードがどのように異なっているかは言いませんが、いくつかの基本クラスや機能の数を減らすことができればうれしいです。

2

あなたは様々なObjを変更することができた場合は、インターフェイスを作成することができます。

public interface IObjectHandler 
{ 
    void Dispatch(); 
} 

は明らかにあなたはそれがために必要なものに署名を変更します。

このインターフェイスをすべてのオブジェクトに置き、それぞれのオブジェクトに関連するコードをDispatchメソッドに実装します。

なく、少なくとも最後に、あなたはこのようにそれを呼び出すことができます。

public dynamic obj1(dynamic obj2) 
{ 
    IObjectHandler tmp = obj2 as IObjectHandler; 
    if(tmp != null) 
     tmp.Dispatch(); 
} 

さて、これは本当にあなたがdynamicを使用しているという事実を利用していません。

public IObjectHandler obj1(IObjectHandler obj2) 

これは明らかにのみ、作成したクラスで動作しますが、あなたはより多くの情報を与えていないことから、これは別のアプローチである。実際のところ、あなたは、この場合でもにあなたの署名を変更することができます。

これはintstringなどのようなもので動作する必要がある場合、これはまったく機能しません。

オブジェクトがすべて異なる継承階層にある場合、さまざまなオプションが表示されます。基本クラスにメソッドを実装し、必要に応じてオーバーライドできます。

0

オーバーロードやインターフェイスを作成したくない場合は、古いswitch caseを使用するか、else ifステートメントを使用することもできます。

+0

私はスイッチが型で動作するとは思わなかったが、C#6で新しくなったのだろうか? –

関連する問題