简体   繁体   English

开放通用类型的ObservableCollection

[英]ObservableCollection of open generic type

I have an interface 我有一个界面

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

    TOut Process(TIn frame);
}

and I needed an observable collection of objects that implement the interface. 我需要一个可观察到的对象集合来实现该接口。

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

the object that i pass to the collection can be 我传递给集合的对象可以是

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

How do it declare the _imageFilters? 如何声明_imageFilters? what's the T? T是多少? or U? 还是你?

Closes you can get to it is 关闭,您可以到达

private ObservableCollection<object> _imageFilters;

If you have control over the IImageFilter, you can do something like: 如果您可以控制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);
      }
    }

and declare the collection like 并像这样声明集合

    private ObservableCollection<IImageFilterBase> _imageFilters;

Not really impossible, Another approach is to use Covariant Generic type. 并非完全不可能,另一种方法是使用协变泛型类型。 But it will require some change in your interface. 但这需要您的界面进行一些更改。

Your Interface: 您的界面:

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

    O Process();
}

Interface Implementation 接口实现

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

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

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

Usage: 用法:

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

The designs of generic interfaces within the Framework, as well as the design of delegates (which provided quasi-generic behavior before real generics were available), require that all generic type parameters be replaced with closed-form generics. 框架中的通用接口的设计以及委托的设计(在提供真正的通用之前,提供了准通用的行为)要求将所有通用类型参数都替换为封闭形式的通用。 It is possible to design interfaces for use with open-form generics, but the interfaces within the framework are not suitable. 可以设计与开放式泛型一起使用的接口,但是框架内的接口不适合。

As a simple example, suppose one wishes to have an interface which is somewhat analogous to Action<T> , but instead of taking a parameter of type T , it will accept one parameter of any type which satisfies two constraints, TC1 and TC2. 举一个简单的例子,假设一个人希望有一个类似于Action<T>的接口,但是它不接受类型T的参数,而是接受一个满足TC1和TC2两个约束的任何类型的参数。 One could define it as: 可以将其定义为:

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

Note that an implementation of that interface would be able to pass a T as a generic parameter to any other method which constrained it to TC1 and TC2 , even if there is no single class which satisfies both constraints and also serves as a base class for all objects that do. 请注意,该接口的实现将能够将T作为通用参数传递给将其限制为TC1TC2任何其他方法,即使没有单个类可以同时满足这两个约束并且也可以作为所有类的基类做对象。

In the case of your observable collection, you should define an observer interface which includes notification methods like those above. 对于可观察的集合,您应该定义一个观察者接口,其中包括上述通知方法。 The event-subscribe method would keep a list of references to the observers; 事件订阅方法将保留对观察者的引用列表。 adding something to the collection should then call the generic notify-of-added-item method on the each item in the list. 向集合中添加一些东西,然后应该在列表中的每个项目上调用通用的notify-of-add-item方法。

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

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