这是我需要定义的界面。我不能,因为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列表中。希望它有意义。
答案 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; }
}