我正在接近一个问题,同时对Generics及其正确的声明/用途仍然有些无知。我得到了前提,但是一些仿制药的内容仍然让我无法理解。
鉴于以下代码(不编译并包含代码味道):
public interface IUIConcern<out T> where T : IUIConcernExtension
{
string Name { get; }
Func<T> Extend();
}
public class UIConcern
{
public static void Register<T>(string concernName, IUIConcern<T> uiConcern) where T : IUIConcernExtension
{
Concerns.Add(uiConcern);
}
public static List<IUIConcern<T>> Concerns{
get {
// Logic...
}
set {
// Logic...
}
}
}
......我有几个问题:
public static void Register<T>(string concernName, IUIConcern<T> uiConcern) where T : IUIConcernExtension
在我已经约束声明T
public interface IUIConcern<out T> where T : IUIConcernExtension
时使用约束
List<>
之外,我怎么能拥有一个IUIConcern<T>
我T
IUIConcernExtension
IUIConcern<>
的属性?同样,我意识到这不会编译并且不正确,只是想看看如何保存可能有许多不同类型的{{1}}元素的通用项列表。
谢谢!
答案 0 :(得分:2)
您需要有一个基本界面,例如:
public interface IUIConcern
{
string Name { get; }
}
public interface IUIConcern<out T> : IUIConcern where T : IUIConcernExtension
{
Func<T> Extern();
}
如何定义Concerns
和Register
取决于您对T
的处理方式。或者,如果您只处理您知道T
的实例,则可以使用Dictionary<Type, List<IUIConcern>>
来保存任何内容,或者可能删除基本界面,只使用object
存储,具体取决于您需要的内容您的控制器代码。
答案 1 :(得分:2)
问题不在于界面,但问题在于使用静态方法和属性的通用实现。
Guvante的答案在说你需要定义IUIConcernExtension
时是正确的,但这当然是非常符合逻辑的,所以我假设你刚刚省略了那部分,因为它对你的问题无关紧要面对。
代码中的问题是您创建了一个具有静态方法和过程的类,通用定义不在类级别,但在方法级别 ,正因为如此,具有的属性和方法不能假设你总是使用相同的类型!!
让我们说你打电话:
Register<string>("something", UIConcern<string>)
但在此之前你已经打过:
Register<Type>("something", UIConcern<Type>)
编译器如何允许你这样做?!所以答案是在类级别定义泛型类型,所有属性和方法都是相同的。
此外,您需要为列表使用私有成员,因为您执行的操作都是静态的,正确的代码应该是:
interface IUIConcernExtension
{
string Name { get; }
}
public interface IUIConcern<out T> where T : IUIConcernExtension
{
Func<T> Extend();
}
public class UIConcern<T> where T : IUIConcernExtension
{
private static List<IUIConcern<T>> _Concerns = new List<IUIConcern<T>>();
public static void Register(string concernName, IUIConcern<T> uiConcern)
{
Concerns.Add(uiConcern);
}
public static List<IUIConcern<T>> Concerns
{
get { return _Concerns; }
set { _Concerns = value; }
}
}