在不知道T的情况下将泛型类型指定为参数param

时间:2013-05-15 18:47:09

标签: c# .net generics

我正在接近一个问题,同时对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}}元素的通用项列表。

谢谢!

2 个答案:

答案 0 :(得分:2)

您需要有一个基本界面,例如:

public interface IUIConcern
{
    string Name { get; }
}

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

如何定义ConcernsRegister取决于您对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; }
    }
}