Reputation: 3249
Here is the interface I need to define. I could not because generic type parameter in Parameters property does not exist. Is there a way to achieve this kind of interface definition in C#?
UPDATED
I did not want to define interface like this: ICriteria<T>
.
public interface ICriteria
{
string Text { get; set; }
IList<IParameter<T>> Parameters { get; set; }
}
UPDATED
As more detail required why I would not want go that route. Here is more information about it. I have Parameter interface and implementaion like this
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; }
}
And the method consumes above implementation like this
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;
}
The above method creates different type of parameters and try to add them to Parameters list in ICriteria interface. Hope it make sense.
Upvotes: 1
Views: 163
Reputation: 58
Maybe you can add constraint for your generic type:
public interface ICriteria<T,S>
where T : IParameter<S>
{
string Text { get; set; }
IList<T> Parameters { get; set; }
}
Upvotes: 0
Reputation: 1500525
As mentioned, you can't do that. But what you could do is this:
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; }
}
A typical implementation would make the WeakParameters
call just return StrongParameters
(assuming you're using C# 4 with generic covariance). Another option would be to make the strong form hide the weak form:
// 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; }
}
Then anything which only had a reference of compile-time type ICriteria
would get the "weak" sequence, whereas anything with a reference of compile-time type ICriteria<T>
would get the "strong" list.
EDIT: This is all assuming that you want a single T
for all parameters on a single ICriteria
instance. If that's not the case, then you might want:
// Parameter types as before
public interface ICriteria
{
string Text { get; set; }
IList<IParameter> Parameters { get; }
}
You can add any kind of IParameter<T>
to it, varying the T
with each call, but when you're reading the parameters you don't have the information (at compile-time) about which parameter has which type (or indeed whether the parameter even implements the strongly-typed interface).
Upvotes: 3
Reputation: 55213
You would need to declare a type parameter T
for your ICriteria
interface in order to use it in its body:
public interface ICriteria<T>
{
string Text { get; set; }
IList<IParameter<T>> Parameters { get; set; }
}
I think this is what your intention is; please let me know if I misunderstood the question.
Upvotes: 4