Question

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? what's the T? or U?

Was it helpful?

Solution 2

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

OTHER TIPS

Closes you can get to it is

private ObservableCollection<object> _imageFilters;

If you have control over the IImageFilter, you can do something like:

    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;

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. 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.

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top