在单个操作中解开可变数量的包装器类型 [英] Unwrap an variable number of wrapper types in a single operation

查看:31
本文介绍了在单个操作中解开可变数量的包装器类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个通用的包装器类型:

I have a generic wrapper type:

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

我可以将任何对象包裹在包裹中或打开包裹对象:

I can wrap any object in a wrap or unwrap a wrapped object:

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;
    }
    //NOP
    public static T Unwrap<T>(this T contents) {
        return contents;
    }
}

这是我如何包装和解开一些字符串:

Here is how I can wrap and unwrap some string:

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

看看我如何需要多次解包才能到达里面的字符串.

See how I need to unwrap multiple times to get to get to the string inside.

我想要的是编写一个强类型的泛型操作,它可以在单个步骤(或固定数量的步骤)中进行解包.一些可能有用的工具是泛型方法、lambda、方法重载.我什至想过从定点组合器构建基于类型的 Y 组合以用于无限递归.即使递归也需要步骤/循环/迭代.

What I want is to write a strongly-typed generic operation that can do the unwrapping in a single step (or constant number of steps). Some tools that might be useful are generic methods, lambdas, method overloads. I even thought about building type-based Y-combinatory from fixed-point combinators to use for unlimited recursion. Even recursion needs steps/cycles/iterations though.

我不确定这是否可以解决,但是 C# 的类型推断可以解决 NP 难题(请参阅 https://blogs.msdn.microsoft.com/ericlippert/2007/03/28/lambda-expressions-vs-anonymous-methods-第五部分/)所以我仍然有可能忽略某些东西.

I'm not sure this is solvable, but C#'s type inference can solve NP-hard problems (see https://blogs.msdn.microsoft.com/ericlippert/2007/03/28/lambda-expressions-vs-anonymous-methods-part-five/) so there is still a tiny chance I'm overlooking something.

推荐答案

这可能有效,但是你失去了类型安全性,而且它肯定不是在一个固定的步骤中:(

This may work, but you lose type safety and it certainly isn't in a constant number of steps :(

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();
        }
    }
}

这篇关于在单个操作中解开可变数量的包装器类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆