是否可以使用C#generic

时间:2011-12-02 06:22:48

标签: c# generics

这是我需要定义的界面。我不能,因为Parameters属性中的泛型类型参数不存在。有没有办法在C#中实现这种接口定义?

已更新 我不想像这样定义界面:ICriteria<T>

public interface ICriteria
{
    string Text { get; set; }
    IList<IParameter<T>> Parameters { get; set; }
}

更新

因为需要更多细节,为什么我不想去那条路。以下是有关它的更多信息。  我有这样的参数接口和实现

public interface IParameter<T>
{
    string Name { get; set; }
    T Value { get; set; }
}

public class Parameter<T> : IParameter<T>
{
    public string Name { get; set; }
    public T Value { get; set; }
}

该方法消耗上述实现

public ICriteria BuildQuery()
    {
        ICriteria criteria = new Criteria();
        criteria.Text = "dbo.Messages";

        var chatRoom = new Parameter<int>() { Name = "ChatRoomId", Value = _chatRoomId };
        var startDate = new Parameter<DateTime>() { Name = "StartDate", Value = _startDateTime };
        var endDate = new Parameter<DateTime>() { Name = "EndDate", Value = _endDateTime };

        //I want to add all parameters to criteria instance
        criteria.Parameters.Add(chatRoom);
        criteria.Parameters.Add(startDate);
        criteria.Parameters.Add(endDate);

        return criteria;
    }

上述方法创建了不同类型的参数,并尝试将它们添加到ICriteria界面中的Parameters列表中。希望它有意义。

3 个答案:

答案 0 :(得分:4)

您需要为T接口声明一个类型参数ICriteria才能在其正文中使用它:

public interface ICriteria<T>
{
   string Text { get; set; }
   IList<IParameter<T>> Parameters { get; set; }
}

我认为这就是你的意图;如果我误解了这个问题,请告诉我。

答案 1 :(得分:3)

如上所述,你不能这样做。但你可以做的是:

public interface IParameter
{
    // Any members which don't need T
}

public interface IParameter<T> : IParameter
{
    // Any members which do need to refer to T
}

public interface ICriteria
{
    string Text { get; set; }
    IEnumerable<IParameter> WeakParameters { get; }
}

public interface ICriteria<T> : ICriteria
{
    IList<IParameter<T>> StrongParameters { get; }
}

典型的实现会使WeakParameters调用返回StrongParameters(假设您使用的是具有通用协方差的C#4)。另一个选择是使强形式隐藏弱形式:

// Parameter types as before

public interface ICriteria
{
    string Text { get; set; }
    IEnumerable<IParameter> Parameters { get; }
}

public interface ICriteria<T> : ICriteria
{
    new IList<IParameter<T>> Parameters { get; }
}

然后只有编译时类型ICriteria的引用的任何东西都会得到“弱”序列,而任何带有编译时类型ICriteria<T>的引用都会得到“强”列表

编辑:这是假设您希望单个T实例上的所有参数都有一个ICriteria。如果那个不是的情况,那么你可能想要:

// Parameter types as before

public interface ICriteria
{
    string Text { get; set; }
    IList<IParameter> Parameters { get; }
}

您可以添加任意类型的IParameter<T>,每次调用都会改变T,但当您读取参数时你没有关于哪个参数具有哪种类型的信息(在编译时)(或者实际上参数是否实现了强类型接口)。

答案 2 :(得分:0)

也许你可以为你的泛型类型添加约束:

   public interface ICriteria<T,S>
        where T : IParameter<S>
    {
        string Text { get; set; }
        IList<T> Parameters { get; set; }
    }