1

我正在解决一个问题,同时仍然对泛型及其正确的声明/使用有一些无知。我明白了前提,但我仍然无法理解泛型的一些细节。

给定以下代码(不编译并包含代码气味):

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<>元素的通用项目列表。

谢谢!

4

2 回答 2

2

您需要有一个基本接口,例如:

public interface IUIConcern
{
    string Name { get; }
}

public interface IUIConcern<out T> : IUIConcern where T : IUIConcernExtension
{
    Func<T> Extern();
}

您将如何定义Concerns并将Register取决于您如何对待T。或者,如果您只处理您知道的实例T,您可以使用 aDictionary<Type, List<IUIConcern>>来保存任何内容,或者可能删除基本接口并object根据您在控制器代码中的需要存储 using 。

于 2013-05-15T18:52:29.677 回答
2

问题不在于接口,而是因为您使用静态方法和属性的通用实现。

Guvante 的回答是正确的,说您需要定义IUIConcernExtension,但这当然是非常合乎逻辑的,所以我假设您刚刚省略了该部分,因为这与您面临的问题无关。

代码中的问题是您创建了一个具有静态方法和过程的类,其通用定义不在类级别而是在方法级别,因此,具有的属性和方法不能假设您总是同类型!!

假设你打电话给 call :

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; }
    }
}
于 2013-05-15T19:49:15.947 回答