ObservableCollection的开放泛型类型

时间:2013-12-04 06:54:43

标签: c# generics observablecollection generic-list

我有一个界面

public interface IImageFilter<TIn, TOut>
{
    // Properties
    TIn Input { get; set; }
    string Name { get; set; }
    Guid Guid { get; set; }

    TOut Process(TIn frame);
}

我需要一个可观察的对象集合来实现接口。

private ObservableCollection<IImageFilter<T, U>> _imageFilters;

我传递给集合的对象可以是

IImageFilter<string, string>
IImageFilter<string, int>
IImageFilter<int, double>

如何声明_imageFilters?什么是T?还是你?

3 个答案:

答案 0 :(得分:3)

关闭你可以得到它

private ObservableCollection<object> _imageFilters;

如果您可以控制IImageFilter,则可以执行以下操作:

    public interface IImageFilterBase {
      object Input { get; set; }
      string Name { get; set; }
      Guid Guid { get; set; }
      object Process(object frame);
    }

    public interface IImageFilter<TIn, TOut> : IImageFilterBase {
      // Properties
      new TIn Input { get; set; }
      TOut Process(TIn frame);
    }

    public abstract class FilterBase<TIn, TOut> : IImageFilter<TIn, TOut> {
      public TIn Input { get; set; }
      public abstract TOut Process(TIn frame);

      object IImageFilterBase.Input {
        get { return this.Input; }
        set { this.Input = (TIn)value; }
      }

      public string Name { get;set;}
      public Guid Guid { get; set; }

      public object Process(object frame) {
        return this.Process((TIn)frame);
      }
    }

    // test class
    public class StringToInt32 : FilterBase<string, int> {
      public override int Process(string frame) {
        return Convert.ToInt32(frame);
      }
    }

并声明像

这样的集合
    private ObservableCollection<IImageFilterBase> _imageFilters;

答案 1 :(得分:2)

并非真的不可能,另一种方法是使用Covariant Generic类型。但它需要对您的界面进行一些更改。

您的界面:

internal interface IImageFilter<out I, out O>
{
    I Input { get; }

    O Process();
}

接口实施

public class ImageFilter : IImageFilter<string, string>
{
    public string Input { get; private set; }

    public ImageFilter(string input)
    {
        Input = input;
    }

    public string Process()
    {
        return Input.ToUpper();
    }
}

用法:

   List<IImageFilter<object, object>> filters= new List<IImageFilter<object, object>>();
   ImageFilter filter= new ImageFilter("something");
   filters.Add(filter);

答案 2 :(得分:2)

框架内的通用接口的设计,以及代表的设计(在真正的泛型可用之前提供了准通用行为),要求所有通用类型参数都用封闭形式的泛型替换。可以设计用于开放式泛型的接口,但框架内的接口不适合。

作为一个简单的例子,假设有人希望有一个类似于Action<T>的接口,但它不接受类型为T的参数,而是接受任何类型的参数满足两个约束,TC1和TC2。可以将其定义为:

interface ActStatisfyingConstraints<in TC1, in TC2>
{
  void Invoke<T>(ref T param) where T:TC1,TC2;
}

请注意,该接口的实现可以将T作为通用参数传递给将其约束为TC1TC2的任何其他方法,即使没有单个类,它满足两个约束,并且还作为所有对象的基类。

对于可观察集合,您应该定义一个观察者界面,其中包含上述通知方法。事件订阅方法将保留对观察者的引用列表;然后,在集合中添加内容应该对列表中的每个项目调用通用的notify-of-added-item方法。