簡體   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