在非泛型基础 class 中定义泛型 属性
define a generic property in non-generic base class
我不认为我想做的事是可能的;有没有办法让这项工作真正发挥作用?
有一个 Base
class 派生出各种不同的 classes。派生的 classes 可以是通用的,也可以不是;派生的 classes 的实例被添加到 WindowViewModel
中类型 Base
的集合中。 Base class 有一个 Options
的集合,由 WindowViewModel
.
访问
问题是:IOption
接口声明了 Func<object, bool> MyFunc
的 return 类型,但是 MyFunc
的 return 类型需要是 Func<T, bool>
用于通用 class 方法 RunIt()
和 MyClass
中的赋值工作。我可以使 IOption
通用,但是 Base
class 需要通用,然后 WindowViewModel.ViewModels
也需要以某种方式重新定义。我不想让 Base 成为泛型,因为在那里引入泛型只会让其他一切变得一团糟。
问题:是否有不同的方法在 IOption
中声明 MyFunc
而不使用泛型以允许在 MyClass
中分配 Func<T,bool>
?
public interface IOption
{
public string Description {get; set;}
public Expression<Func<object,bool>> MyFunc { get; set; }
}
public class Option : IOption
{
public string Description {get; set;}
public Expression<Func<object,bool>> MyFunc { get; set; }
}
public abstract class Base
{
public abstract ObservableCollection<Option> Options { get; set; }
public abstract Option SelectedOption { get; set; }
public abstract void RunIt();
}
public class Generic<T> : Base
{
private DBContext _context;
public override ObservableCollection<Option> Options { get; set; }
public override Option SelectedOption { get; set; }
public Generic()
: base()
{
Options = new ObservableCollection<Option>();
}
public override void RunIt()
{
var result = _context.Set<T>().Where(SelectedOption?.MyFunc);
// process result
}
}
public class MyClass : Generic<MyType>
{
public MyClass
: base()
{
Func<MyType,bool> expression = t => t.MyDescription = "Hello World";
Options.Add(new Option("Hi", expression)); // fail to compile type mismatch
SelectedOption = Options.First();
}
}
public class Special : Base
{
// do something else
}
public class WindowViewModel
{
public WindowViewModel ()
{
MyViewModels = new ObservableCollection<Base>();
MyViewModels.Add(new Special());
MyViewModels.Add(new MyClass());
}
public ObservableCollection<Base> MyViewModels {get; set;}
public Base SelectedViewModel { get; set; }
public void DoRunIt()
{
SelectedViewModel.RunIt();
}
}
我尝试过的其中一个编译但在使用时抛出运行时异常的事情是
Func<MyType,bool> expression = t => t.MyDescription = "Hello World";
MyFunc = t => expression((MyType)t);
Question: is there a different way to declare MyFunc in IOption without using generics to allow assignment of Func<T,bool> in MyClass ?
不,我不认为这是可能的。不过,您可以在非泛型类型中使用泛型方法。
但是,有一个选项可能适合您。
你说
I dont want to make the Base generic as introducing generics there just makes everything else a real mess.
两者兼而有之如何?
public abstract class Base<T>
{
public abstract ObservableCollection<Option<T>> Options { get; set; }
public abstract Option<T> SelectedOption { get; set; }
public abstract void RunIt();
}
public abstract class Base : Base<object> { }
有一种方法可以做到这一点。它使用将所有委托(Func<MyType, bool>
是委托)强制转换为 Delegate
.
的能力
您将 IOption
和 Option
更改为:
public interface IOption
{
public string Description { get; set; }
Func<T, bool> GetMyFunc<T>();
}
public class Option : IOption
{
string description;
private Delegate expression;
public Option(string description, Delegate expression)
{
this.description = description;
this.expression = expression;
}
public string Description { get; set; }
public Func<T, bool> GetMyFunc<T>() => (Func<T, bool>)this.expression;
}
然后 MyClass
按预期工作(除了代码中的其他语法错误)。
然后您只需将 Generic<T>
上的 RunIt
更改为:
public override void RunIt()
{
var result = _context.Set<T>().Where(SelectedOption?.GetMyFunc<T>());
// process result
}
我不认为我想做的事是可能的;有没有办法让这项工作真正发挥作用?
有一个 Base
class 派生出各种不同的 classes。派生的 classes 可以是通用的,也可以不是;派生的 classes 的实例被添加到 WindowViewModel
中类型 Base
的集合中。 Base class 有一个 Options
的集合,由 WindowViewModel
.
问题是:IOption
接口声明了 Func<object, bool> MyFunc
的 return 类型,但是 MyFunc
的 return 类型需要是 Func<T, bool>
用于通用 class 方法 RunIt()
和 MyClass
中的赋值工作。我可以使 IOption
通用,但是 Base
class 需要通用,然后 WindowViewModel.ViewModels
也需要以某种方式重新定义。我不想让 Base 成为泛型,因为在那里引入泛型只会让其他一切变得一团糟。
问题:是否有不同的方法在 IOption
中声明 MyFunc
而不使用泛型以允许在 MyClass
中分配 Func<T,bool>
?
public interface IOption
{
public string Description {get; set;}
public Expression<Func<object,bool>> MyFunc { get; set; }
}
public class Option : IOption
{
public string Description {get; set;}
public Expression<Func<object,bool>> MyFunc { get; set; }
}
public abstract class Base
{
public abstract ObservableCollection<Option> Options { get; set; }
public abstract Option SelectedOption { get; set; }
public abstract void RunIt();
}
public class Generic<T> : Base
{
private DBContext _context;
public override ObservableCollection<Option> Options { get; set; }
public override Option SelectedOption { get; set; }
public Generic()
: base()
{
Options = new ObservableCollection<Option>();
}
public override void RunIt()
{
var result = _context.Set<T>().Where(SelectedOption?.MyFunc);
// process result
}
}
public class MyClass : Generic<MyType>
{
public MyClass
: base()
{
Func<MyType,bool> expression = t => t.MyDescription = "Hello World";
Options.Add(new Option("Hi", expression)); // fail to compile type mismatch
SelectedOption = Options.First();
}
}
public class Special : Base
{
// do something else
}
public class WindowViewModel
{
public WindowViewModel ()
{
MyViewModels = new ObservableCollection<Base>();
MyViewModels.Add(new Special());
MyViewModels.Add(new MyClass());
}
public ObservableCollection<Base> MyViewModels {get; set;}
public Base SelectedViewModel { get; set; }
public void DoRunIt()
{
SelectedViewModel.RunIt();
}
}
我尝试过的其中一个编译但在使用时抛出运行时异常的事情是
Func<MyType,bool> expression = t => t.MyDescription = "Hello World";
MyFunc = t => expression((MyType)t);
Question: is there a different way to declare MyFunc in IOption without using generics to allow assignment of Func<T,bool> in MyClass ?
不,我不认为这是可能的。不过,您可以在非泛型类型中使用泛型方法。
但是,有一个选项可能适合您。 你说
I dont want to make the Base generic as introducing generics there just makes everything else a real mess.
两者兼而有之如何?
public abstract class Base<T>
{
public abstract ObservableCollection<Option<T>> Options { get; set; }
public abstract Option<T> SelectedOption { get; set; }
public abstract void RunIt();
}
public abstract class Base : Base<object> { }
有一种方法可以做到这一点。它使用将所有委托(Func<MyType, bool>
是委托)强制转换为 Delegate
.
您将 IOption
和 Option
更改为:
public interface IOption
{
public string Description { get; set; }
Func<T, bool> GetMyFunc<T>();
}
public class Option : IOption
{
string description;
private Delegate expression;
public Option(string description, Delegate expression)
{
this.description = description;
this.expression = expression;
}
public string Description { get; set; }
public Func<T, bool> GetMyFunc<T>() => (Func<T, bool>)this.expression;
}
然后 MyClass
按预期工作(除了代码中的其他语法错误)。
然后您只需将 Generic<T>
上的 RunIt
更改为:
public override void RunIt()
{
var result = _context.Set<T>().Where(SelectedOption?.GetMyFunc<T>());
// process result
}