c# - Contravariant Value Types -
i have created interface repositories.
public interface irepository<t, in tkey> t: class { ienumerable<t> find(expression<func<t, bool>> predicate); ienumerable<t> findall(); t findsingle(tkey id); void create(t entity); void delete(t entity); void update(t entity); }
the findsingle
method accepts id, used searching on primary key. using in
expected allowed pass reference type tkey
. out of curiosity decided create concrete class , specify int, see exception.
i looked msdn , specifies should not work
covariance , contravariance in generic type parameters supported reference types, not supported value types.
the class created looks this
public class projectrepository : irepository<project,int> { public ienumerable<project> find(expression<func<project, bool>> predicate) { throw new notimplementedexception(); } public ienumerable<project> findall() { throw new notimplementedexception(); } public project findsingle(int id) { throw new notimplementedexception(); } public void create(project entity) { throw new notimplementedexception(); } public void delete(project entity) { throw new notimplementedexception(); } public void update(project entity) { throw new notimplementedexception(); } }
why did not exception on build having specified tkey
value type? also, if removed in
parameter have lost? msdn document says contravariance allows using less derived type, surely removing in
can pass type in still generic.
this maybe displaying lack of understanding on contravariance , covariance has me little confused.
covariance , contravariance don't make sense on value types, because sealed. though it's not clear documentation, valid use struct
co/contravariant type, it's not useful. documentation reference referring following not valid:
public struct mystruct<in t>
contravariance means can following example:
irepository<string, base> b = //something irepository<string, derived> d = b;
since there's nothing derives int
, can use irepository<string, int>
, irepository<string, int>
.
covariance means can reverse, e.g. ienumerable<t>
out t
, covariant. can following:
ienumerable<derived> d = //something ienumerable<base> b = d;
if you're trying restrict both tkey
, t
class
es (reference types), should include second restriction:
public interface irepository<t, in tkey> t : class tkey : class
Comments
Post a Comment