繁体   English   中英

如何创建具有泛型类型的接口集合

[英]How to create a collection of interfaces that have a generic type

我正在尝试制作一个可由实施者扩展的框架。 在高层次上,一个基础对象会有几个不同的实现,这些不同实现的所有实例都需要一起处理。 对于实现者来说,最通用和最优雅的解决方案似乎是通用类型,但是将它们放在一个集合中让我感到困惑。

我尝试使用具有泛型类型的类或接口,然后实现修复了它,但我无法构建列表。 例如

using System;
using System.Collections.Generic;

namespace GenericsMixingExample
{
    class Program
    {
        static void Main(string[] args)
        {
            var container = new Container();
            container.Wrappers.Add(new IntWrapper { Value = 5 });
            container.Wrappers.Add(new IntWrapper { Value = 5 });
            container.Wrappers.Add(new StringWrapper { Value = "value" });
            container.Wrappers.ForEach((e) => { Console.WriteLine(e.Value.ToString()); });
        }
    }

    interface ValueWrapper<T>
    {
        T Value { get; set; }
    }

    class IntWrapper : ValueWrapper<int>
    {
        public int Value { get; set; }
    }

    class StringWrapper : ValueWrapper<string>
    {
        public string Value { get; set; }
    }

    interface IContainer
    {
        List<ValueWrapper> Wrappers { get; set; }
    }

    class Container : IContainer
    {
        public List<ValueWrapper> Wrappers { get; set; }
        public Container()
        {
            Wrappers = new List<ValueWrapper>();
        }
    }
}

但这会导致错误Using the generic type 'ValueWrapper<T>' requires 1 type arguments当我尝试定义列表时

我想也许一个返回object然后覆盖类型的抽象类会起作用:

using System;
using System.Collections.Generic;

namespace objectBased
{
    class Program
    {
        static void Main(string[] args)
        {
            var container = new Container();
            container.Wrappers.Add(new IntWrapper { Value = 5 });
            container.Wrappers.Add(new IntWrapper { Value = 5 });
            container.Wrappers.Add(new StringWrapper { Value = "value" });
            container.Wrappers.ForEach((e) => { Console.WriteLine(e.Value.ToString()); });
        }
    }

    abstract class IValueWrapper
    {
        public virtual object Value { get; set; }
    }

    class IntWrapper : IValueWrapper
    {
        private int _value;
        public override object Value {
            get { return _value; }
            set { _value = Convert.ToInt32(value); }
        }
    }

    class StringWrapper : IValueWrapper
    {
        private string _value;
        public override object Value
        {
            get { return _value; }
            set { _value = (value as string); }
        }
    }

    interface IContainer
    {
        List<IValueWrapper> Wrappers { get; set; }
    }

    class Container : IContainer
    {
        public List<IValueWrapper> Wrappers { get; set; }
        public Container()
        {
            Wrappers = new List<IValueWrapper>();
        }
    }
}

但是当我尝试添加更多复杂性时,这会崩溃:

abstract class IValueWrapper
    {
        public virtual object Value { get; set; }
        public abstract void Randomize();
        public abstract object MixValues(object otherValue);
    }

    class IntWrapper : IValueWrapper
    {
        public static int MAX_RANDOM = 100;
        private int _value;
        public override object Value {
            get { return _value; }
            set { _value = Convert.ToInt32(value); }
        }
        public override void Randomize()
        {
            Random rng = new Random();
            Value = rng.Next(0, MAX_RANDOM);
        }
        public override int MixValues(int otherValue)
        {
            int smaller = Math.Min(otherValue, Value);
            int larger = Math.Min(otherValue, Value);
            return smaller - (larger - smaller) / 2;
        }
    }

在上面的块中,MixValues 不能覆盖抽象,因为返回类型不同,输入类型不同,而且 Value 不是 int。 抽象类方法看起来需要大量我不太感兴趣的转换。

作为一个延伸目标,我希望能够让像 mix 这样的方法成为返回类的新实例的静态方法

public static IntWrapper MixValues()
{
    return new IntWrapper() //...etc
}

但如果它一定很困难,我可以没有它

那么有什么方法可以制作通用类型的父对象列表吗?

取决于你想用处理做什么,但也许你可以做这样的事情?

using System;
using System.Collections.Generic;

namespace GenericsMixingExample
{
    class Program
    {
        static void Main(string[] args)
        {
            var container = new Container();
            container.Wrappers.Add(new IntProcessor { Value = 5 });
            container.Wrappers.Add(new IntProcessor { Value = 5 });
            container.Wrappers.Add(new StringProcessor { Value = "value" });
            container.Wrappers.ForEach((e) => { e.Process(); });
        }
    }

    interface IProcessor
    {
        void Process();
    }

    class IntProcessor : IProcessor
    {
        public int Value { get; set; }

        public void Process()
        {
            Console.WriteLine("Processing: " + Value);
        }
    }

    class StringProcessor : IProcessor
    {
        public string Value { get; set; }

        public void Process()
        {
            Console.WriteLine("Processing: " + Value);
        }
    }

    interface IContainer
    {
        List<IProcessor> Wrappers
        {
            get;
            set;
        }
    }

    class Container : IContainer
    {
        public List<IProcessor> Wrappers
        {
            get;
            set;
        }
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM