是否可以使用c#泛型

本文关键字:泛型 可以使 是否 | 更新日期: 2023-09-27 18:16:40

这是我需要定义的接口。不能,因为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;
    }

上面的方法创建了不同类型的参数,并尝试将它们添加到iccriteria接口的parameters列表中。

是否可以使用c#泛型

您需要为您的ICriteria接口声明一个类型参数T,以便在其主体中使用它:

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

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

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

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>的引用都将得到"强"序列。

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

// Parameter types as before
public interface ICriteria
{
    string Text { get; set; }
    IList<IParameter> Parameters { get; }
}

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

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

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