我有一个界面
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?还是你?
答案 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
作为通用参数传递给将其约束为TC1
和TC2
的任何其他方法,即使没有单个类,它满足两个约束,并且还作为所有对象的基类。
对于可观察集合,您应该定义一个观察者界面,其中包含上述通知方法。事件订阅方法将保留对观察者的引用列表;然后,在集合中添加内容应该对列表中的每个项目调用通用的notify-of-added-item方法。