2017-06-08 15 views
0

単一の操作でラッパー型の可変数のラップを解除私はいくつかの文字列をラップし、アンラップことができる方法です。私は、一般的なラッパー型を持っている

string s = "ssss"; 
var wrappedString = s.Wrap().Wrap().Wrap(); 
string unwrappedString = wrappedString.Unwrap().Unwrap().Unwrap().Unwrap().Unwrap().Unwrap(); 

は私がstrinに到達するために取得するために複数回のラップを解除する必要があるかを参照してください。内部にg。

私が望むのは、単一ステップ(または一定のステップ数)でアンラッピングを実行できる強く型付けされた汎用操作を記述することです。 便利なツールには、汎用メソッド、ラムダ、メソッドオーバーロードがあります。私は無制限の再帰に使用する固定小数点コンビネータからタイプベースのY結合を構築することについても考えました。再帰でさえ、ステップ/サイクル/反復が必要です。

これは解決できないのですが、C#の型推論ではNP困難な問題(https://blogs.msdn.microsoft.com/ericlippert/2007/03/28/lambda-expressions-vs-anonymous-methods-part-five/参照)を解決できるため、何かを見落としてしまう可能性はまだあります。

+0

・ダウト、各ラッピングレベル( 'アンラップ(のために過負荷を加えることなく、このラップ>ラップされた) 'など)このようなシナリオでは実際の使用方法はありますか? – Evk

+0

@Evk"各ラッピングレベルのオーバーロード "おそらく対数的なステップ数を使用する方法があります。タプルベースの複数型のリンクリストを逆順にしたい場合など、同様の手法が必要です。 –

+0

C#型システムでは、あなたが望むものはできません。 – Evk

答えて

0

これは動作する可能性がありますが、型の安全性を失い、それは確かにステップ:(一定の数ではありませんあなたが行うことができます

using System; 
using System.Collections.Generic; 
using System.Linq; 


namespace Test 
{ 
    public class Wrap<T> 
    { 
     public T Contents { get; set; } 

     public object DeepUnwrap() 
     { 
      var wrapped = this; 
      var hello = wrapped.Unwrap(); 

      if (hello != null) 
      { 
       var type = hello.GetType(); 

       if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Wrap<>)) 
        return ((dynamic)hello).DeepUnwrap(); 
      } 

      return hello; 
     } 

    } 

    public static class WrapHelpers 
    { 
     public static Wrap<T> Wrap<T>(this T contents) 
     { 
      return new Wrap<T> { Contents = contents }; 
     } 
     public static T Unwrap<T>(this Wrap<T> wrapped) 
     { 
      return wrapped.Contents; 
     } 

     public static object FullUnwrap<T>(this Wrap<T> wrapped) 
     { 
      var hello = wrapped.DeepUnwrap(); 

      return hello; 
     } 

     //NOP 
     public static T Unwrap<T>(this T contents) 
     { 
      return contents; 
     } 
    } 

    public class Program 
    { 
     public static void Main(string[] args) 
     { 
      string s = "ssss"; 
      var wrappedString = s.Wrap().Wrap().Wrap(); 
      Console.WriteLine(wrappedString.FullUnwrap()); 
      Console.ReadLine(); 
     } 
    } 
} 
+0

"は一定のステップ数ではありません" - 私にとっては、あなたのソリューションは ".FullUnwrap()"を呼び出すと1ステップでアンラッピングするので、一定数の呼び出しステップを持ちます。残念なことに、厳密な型指定に違反しています。例えば、私の 'wrappedString.Unwrap()..... Unwrap()==" ssss "'は 's ==" ssss "'と同じようにコンパイル/動作しますが、 'wrappedString.FullUnwrap()== "ssss"はコンパイルしたり、同じことをしません。 –

+0

真実、良い呼出し。 – mjwills

関連する問題