I've read an excellent article on MSDN regarding Generics in C#.
The question that popped in my head was - why should i be using generic constraints?
For example, if I use code like this:
public class MyClass<T> where T : ISomething
{
}
can't I switch ALL references of T in this class with ISomething?
What's the benefit of using this approach?
You ask, "can't I switch ALL references of T in this class with ISomething?" So I think you mean to compare:
public class MyClass<T> where T : ISomething
{
public T MyProperty { get; set; }
}
With:
public class MyClass
{
public ISomething MyProperty { get; set; }
}
In the second example, MyProperty is only guaranteed to be an instance of ISomething. In the first example, MyProperty is whatever T is, even if that is a specific subtype of ISomething. Consider a concrete implementation of ISomething:
public class MySomething : ISomething
{
public string MyOtherProperty { get; set; }
}
Now, if we use the first, generic, example, we could have:
MyClass<MySomething> myClass = new MyClass<MySomething>();
Console.WriteLine(myClass.MyProperty.MyOtherProperty);
On the other hand, if we used the second example, we wouldn't be able to access MyOtherProperty since it's only known to be an ISomething:
MyClass myClass = new MyClass();
Console.WriteLine(myClass.MyProperty.MyOtherProperty); // Won't compile, no property "MyOtherProperty"
On a different note, the reason these type constraints are useful is that you can refer to MyProperty (type T) and access members of ISomething. In other words, if ISomething were declared like:
public interface ISomething
{
public string SomeProperty { get; set; }
}
Then you could access MyProperty.SomeProperty. If you omitted the where T : ISomething then you wouldn't be able to access SomeProperty since T would only be known to be of type object.
Type Safety. For example, suppose you're creating a container. You can pass in something to that container and retrieve it in the proper form without having to do any casts later by parameterizing the container. You're simply defining constraints on the types of things that you're willing to store in your container.
Here's an example of the difference, by just using List<>
Image list wouldn't be generic but it would just use IListElement everywhere it used the generic instead. Now Imagine you have an object that's something like this.
class Element : IListElement
{
public string Something { get; set; }
}
now I could just do list.Add(element); and there wouldn't be a difference with a real List<Element>. However when I retreive data it's a different story, if I use the list that uses IListElement then I have to cast my data back so I can get the Something out of it. Thus i'd have to do:
string s = ((Element)list[0]).Something;
while with the generic I can just do:
string s = list[0].Something;
saves a lot of trouble, ofcourse it goes a bit further than that but I think you can get the idea from this.
Well for a start, you can call methods defined in ISomething within the code for the generic method / methods on the generic class. If T was allowed to be any type then this would not be possible (although you could always do some runtime casting).
So it allows you to enforce compile-time constraints on what T can be and therefore rely on these constraints when you write the code - turning runtime errors into compile time errors.
Yes you can use ISomething in place of T , but that will manually close the generic type to an ordinary class. It wont be a generic type any more. By using T, you keep the type open to as many ISomething subtypes as you want. Code reuse without compromising type safety is the key benefit here. For example if you use a Stack of ISomethings, you can push any ISomething onto the stack but a pop has to occur with a downcast to the actual subtype of ISomething for it to be useful. Downcasting creates a potential failure point, which will not be there in a generic Stack<T> where T:ISomething
Consumer of your class gets the benefit of increased type-safety, among others.
class Widget : IPokable { }
// No generics
Widget w = (Widget)list[0]; // cast can fail
// With generics
Widget w = list[0];
Without generics, if list was containing IPokable objects, cast is still necessary.
Class you're implementing gets the benefit of using specific methods on the generic object.
class PokableList<T> where T : IPokable {
public T PokeAndGet() {
currentObj.Poke();
return currentObj;
}
}
Perhaps this simple example might help.
If I have these classes:
public class ListOfCars<T> : List<T> where T : Car { }
public abstract class Car { }
public class Porsche : Car { }
public class Bmw : Car { }
...and then if I write this code:
var porsches = new ListOfCars<Porsche>();
// OK
porsches.Add(new Porsche());
//Error - Can't add BMW's to Porsche List
porsches.Add(new Bmw());
You can see that I can't add a BMW to a Porsche list, but if I just programmed off of the base class it would be allowed.
Related
I want to do something like this:
public class MyAttribute : Attribute
{
public Type<BaseAllowedType>[] handledTypes { get; set; }
//...elided...
}
That would then only allow someone adding the attribute with the types that they handle if those types inherit from BaseAllowedType.
Example:
[MyAttribute(handledTypes = SubType)]
public class MyClass
{
}
public class SubType : BaseAllowedType
{
}
Is something like this possible in C#? (It is in Java, but not sure if C# allows it)
In Java it would be public Class<? extends BaseAllowedType>[] handledTypes
First off, that is a property, not a field.
Second, properties cannot be genericized in C#, and neither can attributes. (And neither can fields, for that matter. Only classes, structs, interfaces, delegates and methods can be genericized.)
That said, we can take a stab at your question.
There are two ways to put a constraint on a generic type parameter. The first is to put a constraint on the declaration of a generic class or method:
class Foo<T> where T : Animal {}
Now Foo<Giraffe> or Foo<Animal> or Foo<Turtle> are legal, but Foo<string> is not.
Second, on interfaces and delegates you can put a covariance annotation:
interface IFoo<out T>
{
T SomeProperty { get; }
}
But T must be used only in output positions. With this constraint you can assign an IFoo<Giraffe> to a variable of type IFoo<Animal>, but not vice-versa.
Between those two features it is usually possible to build a reasonable type constraint in C#.
Intro
I am creating an ASP.NET Web API application with Entity Framework. What I need to do is return different representations of the same resource for one URI, depending on user role. For example, api/employees/1 will return two different objects for admin and standard user:
Standard user
public class EmployeeBasic
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
Admin
public class EmployeeExtended : EmployeeBasic
{
public decimal Salary { get; set; }
}
The idea and the attempts
For each resource representation, I will need to provide some related classes, let's say Sort Models for example. I was wondering if it is possible to use generic types and inheritance to create a generic repository methods for related representations. I thought of the following way of doing this:
Create some base interface for Sort Models:
public interface ISortModel<out TBusinessEntity>
{
//
}
Create generic SortModel as a base type for all sort models
public abstract class SortModel<TDBEntity, TBusinessEntity> : ISortModel<TBusinessEntity>
{
// Database sorting
public abstract IQueryable<TDBEntity> ApplyToQuery(IQueryable<TDBEntity> query);
// Local sorting
public abstract IEnumerable<TBusinessEntity> ApplyToLocal(IEnumerable<TBusinessEntity> localList);
// ...
// Some private logic (expression mappers, etc.)
}
Create sort model for basic resource
public class EmployeeBasicSortModel : SortModel<DBModel.Employee, EmployeeBasic>
{
public int FullName { get; set; }
public override IQueryable<DBModel.Employee> ApplyToQuery(IQueryable<DBModel.Employee> query)
{
// implementation
}
public override IEnumerable<EmployeeBasic> ApplyToLocal(IEnumerable<EmployeeBasic> localList)
{
// implementation
}
}
Extend the basic sort model and add sorting for the extended resource properties
public class EmployeeExtendedSortModel : EmployeeBasicSortModel //, ... Is it possible to somehow do that?
{
public override IEnumerable<EmployeeExtended> ApplyToLocal(IEnumerable<EmployeeExtended> localList)
{
var partiallyOrderedList = base.ApplyToLocal(localList);
// Add extended sorting
}
// ... ?
}
Use the above classes to create generic service:
class EmployeesService()
{
public IList<TEmployee> GetAll<TEmployee>(ISortModel<TEmployee> sortModel)
where TEmployee : BasicEmployee
{
// implementation
}
}
The problem
When I thought about it for the first time, it seemed pretty simple. But when I started implementing this, I couldn't figure out the way to implement Step 4. Either I am missing something in my C# knowledge (which is quite possible) or this is not possible in the way I am trying to do this.
So the question is: can I create a base class with generic type, derive from it with basic resource as a type and derive one more time with the extended class?
Holy goodness this is a complicated question. The generics are a huge red herring. Ignore the generics; the problem is more fundamental. Let's simplify it greatly.
class Animal {}
class Mammal : Animal {}
class Tiger : Mammal {}
class Shape {}
class Square : Shape {}
class GreenSquare : Square {}
class B
{
public virtual Mammal Frob(Square s) { ... }
}
class D : B
{
public override SomeReturnType Frob(SomeArgumentType m) { ... }
}
The question is: what are legal return and argument types for this virtual override?
The answer is: in C# the only legal types are those that exactly match the overridden method's types. An override of Frob must return Mammal and take Square.
Now, we could in theory make it typesafe for D.Frob to return Tiger. Do you see why? If we have a D converted to B, then it returns a Tiger, but a Tiger is an Animal, so we're OK.
This feature is called return type covariance, and it has been suggested for C# for, oh, some 15 years now, and has never been implemented. It is not supported by the CLR, and it is not a high priority for the design team, and it creates new flavours of the Brittle Base Class Problem, and all these are such points against that it is unlikely to meet the bar any time soon.
C++ does support this feature, including on the CLR, so it is possible to do on the CLR. You just end up having to generate a bunch of helper methods.
Of course we cannot have D.Frob return Animal. It could return a Turtle, but B.Frob promises to only return Mammals.
What about the argument type? It could be typesafe to have D.Frob take Shape. Again, same reasoning: if we have a D converted to B then we will only get squares. But it would not be safe to have D.Frob take a GreenSquare, because B.Frob promises to be able to take any square, not just green squares.
This feature is called formal parameter type contravariance and few languages implement it.
Now, you want return type covariance and formal parameter type covariance, which is neither supported nor typesafe. Interestingly enough, Eiffel supports this kind of covariance.
C# developers who want return type covariance usually end up doing something like:
class D : B {
private Tiger FrobPrivate(Square s) { ... }
public override Mammal Frob(Square s)
{
return this.FrobPrivate(s);
}
public new Tiger Frob(Square s)
{
return this.FrobPrivate(s);
}
}
Which is basically what the C# compiler would have to do on your behalf to implement the feature anyways.
I know the title may be a little unclear, so I'll explain what I'm trying to do.
Note, this is more for educational reasons around the language's capabilities. In other words if this is possible, not should this be the way to go about it.
Consider the following generic class:
public class Foo<TId>
{
TId Id { get; set; }
}
Now consider concrete subclasses based on the above. Here's two examples using 'int' and 'string'...
public class IntFoo : Foo<int>
{
}
public class StrFoo : Foo<string>
{
}
And finally a generic that takes a Foo as a type parameter, and inherits from a Laa which takes its type parameter from Foo.
public class BaseClass<TFoo, TFooId> : Laa<TFooId>
{
}
public class Laa<TFooId>
{
}
Here's how you'd do the one based on an int and string, but note in addition to IntFoo and StrFoo, I have to also define int and foo explicitly...
public class IntFinal : BaseClass<IntFoo, int>
{
char somePropSpecificToIntFinal{ get; set; }
}
public class StrFinal : BaseClass<StrFoo, string>
{
char somePropSpecificToStrFinal{ get; set; }
}
Note that these 'final' classes are concrete types with their own properties which can't be reduced to a generic that takes a type (i.e. using a generic with the single type T, that then subclasses another generic that takes Foo and T as its arguments.
I'm wondering is if there's a way to have that type inferred so it can be written like so...
public class IntFinal : BaseClass<IntFoo>
{
}
public class StrFinal : BaseClass<StrFoo>
{
}
...and have the type for Laa implied from the generic specified on Foo. Here's a pseudo-code example of what I want.
public class BaseClass<TFoo> : Laa<TFoo.IdType>
{
}
So is that possible in C#?
Note, if this can't be done with classes, can it be done with interfaces?
Consider this...
interface IFoo
{
Type FoosType { get; }
}
public class Foo<TId> : Foo
{
TId Id { get; set; }
Type FoosType { get{ return TId } }
}
Then do this...
public class BaseClass<TFoo> : Laa<TFoo.FoosType>
where TFoo : Foo
{
}
(Note: FoosType would have to be static technically, and you can't inherit using statics so again, this is pseudo-code.)
If you constrained TFoo to IFoo, could you then use 'FoosType' as the type specifier when defining Laa?
You can't do that based on the C# specification. Type inference currently works for methods only and doesn't work for types (classes like your case)
Second rule that breaks your needed result is that you can't specify one generic type argument and infer the other, it is Provide all or Infer all case for methods.
C# specification:
1.6.3 Type parameters
When the generic class is used, type arguments must be provided for each of the type parameters
Your question is not very specific, and it's not clear what the actual constraints and requirements are. That said…
Type inference only occurs for generic methods, not generic types. So taking your question literally, the answer is no, there is no way to infer the type.
What might work for you is to use Foo<TId> in the class definition instead of IntFoo:
class BaseClass<TFooId> : Laa<TFooId>
{
public Foo<TFooId> Method() { ... }
}
(Of course, you can apply the type anywhere appropriate: fields, property types, etc.)
I.e. instead of coding the BaseClass type with two type parameters, just use the one that uniquely defines the interesting/useful elements of the Foo<TFooId> base class you're using, and then use that base type instead of the more-derived IntFoo
In your example, you have no constraints for the TFoo class, so it's not like BaseClass<TFoo, TFooId> was going to be able to use even the base type class members from Foo<TId> anyway. But even if you did mean to constrain TFoo to Foo<TFooId>, it seems likely you wouldn't really need to specify that type anyway.
If the above is not useful, then you need to add a lot more detail to your question, to explain precisely what is needed. Consider also that it's likely people have already gone down this road, and that if you express your question less about the mechanics of the implementation you think you need, you instead phrase it at a higher level, you might likely find existing questions on Stack Overflow or articles elsewhere that already address that broader question.
At the very least, if you are unable to find such references yourself, expressing your question that way may yield better answers faster.
See also XY Problem.
I saw a C# class SomeClass that was defined like
public class SomeClass : IComparable<SomeClass>, IEquatable<SomeClass>
{
// ...
}
and I'm wondering how to translate that into English. The way I understand it seems logically impossible. How can a class inherit from a parameterized version of itself? Also, is this a common design pattern?
The key is to recognize that it's not inheriting from (or implementing) a parameterized version of itself, but rather inheriting from (or implementing) another class or interface, and using itself as a generic parameter for that target type.
For example, IComparable<T> says that there will be a CompareTo() method that takes an object of type T as a parameter. So by implementing IComparable<SomeClass> you're simply guaranteeing that a method with that signature will exist on this class:
public class SomeClass : IComparable<SomeClass>
{
public int CompareTo(SomeClass other)
{
//...
}
}
And yes, this is fairly common practice. Classes often implement the generic IComparable<> and IEquatable<> interfaces to show that they can be compared with other items of the same type. It's maybe also worth mentioning that enums in Java are declared as extending Enum<> of themselves--a pattern which is not common in C#, but does appear from time to time.
Translated in "English" it means: "Boy (or girl), you'd better be type-safe when implementing those interfaces, especially IComparable. Otherwise, you'll have to perform type casting, which I guess you don't want"
See the code below. SomeClass implemented IComparable and IComparable.
See differencies between implementations of CompareTo(object) and CompareTo(SomeClass).
namespace InterfacesStuff
{
internal class Program
{
private static void Main(string[] args)
{
var someClass1 = new SomeClass {ComparedValue = 1};
var someClass2 = new SomeClass {ComparedValue = 2};
//someClassObject defined as SomeClass
//object someClassObject = new SomeClass { ComparedValue = 2 };
//someClassObject defined as anything else but SomeClass
object someClassObject = 5;
int comparisonSomeClassBySomeClass = someClass1.CompareTo(someClass2);
int comparisonSomeClassByObject = someClass1.CompareTo(someClassObject);
}
}
public class SomeClass : IComparable, IComparable<SomeClass>, IEquatable<string>, IEquatable<int>,
IEquatable<double>
{
public int ComparedValue;
public int CompareTo(object obj)
{
var presumedSomeClassObject = obj as SomeClass;
if (presumedSomeClassObject != null)
{
if (ComparedValue <= ((SomeClass) obj).ComparedValue)
return -1;
}
return 0;
}
public int CompareTo(SomeClass other)
{
if (ComparedValue <= other.ComparedValue)
return -1;
return 0;
}
public bool Equals(double other)
{
throw new NotImplementedException();
}
public bool Equals(int other)
{
throw new NotImplementedException();
}
public bool Equals(string other)
{
throw new NotImplementedException();
}
}
}
It is not Inheriting, It is implementing the IComparable Interface. what is going on is
Someclass Implements the Icomparable and the IEquatable interface. Implementing an interface is like signing a contract stating you gaurentee that this class will implement the methods on an interface.
Icomparable msdn, IEquatable. If you look at the MSDN pages you can see that SomeClass gaurentees it will implement the methods in some fashion.
This is very common practice and it is many different names. The ones I hear most are programming by contract and Implementation over Inhertience. It lets you do a lot of cool things, like Dependency Injection, Proper Unit testing, better Generics. It does this because the compiler doesnt need to know the concrete class that your object is implementing. It just needs to know that it has certain functions on it. For further reading on this I would read Chapter one of the gang of four Design pattern book.
Wikipedia link Specifically the Introduction to Chapter one section
It doesn't really have to be convenient to express it in english for it to be valid code, although I'd probably read that as "SomeClass is comparable and equatable to itself". That doesn't really explain what's going on though, it's just a way of expressing it.
In C# types can be generic over categories of other types. Generic types are basically "type constructors". They take other types as parameters, and use them to construct new types. For instance, IEnumerable<int> and IEnumerable<string> are two completely different types. The non-generic version (IEnumerable) is a third one. In C# a type A can inherit ANY other type B as long as none of the following is true (I hope I didn't miss anything):
B is already a subtype of A
B is a class and A has already inherited another class
B is a struct
A is an interface but B is not
A is the same type as B
B is sealed
A is a struct and B is not an interface
This even makes the following code legal:
class Foo<T>
{
public T Value;
}
class Foo : Foo<int>
{
}
Foo and Foo<T> are different types, so there's no problem at all for one to inherit the other.
You can read more about generics here:
https://msdn.microsoft.com/en-us/library/ms379564(v=vs.80).aspx
And about inheritance here:
https://msdn.microsoft.com/en-us/library/ms173149.aspx
The code you posted does not inherit from any class. It is implementing certain so-called Interfaces. How to translate that snippet: "I guarantee that SomeClass will be Comparable and equatable with other SomeClass instances. I will provide definitions in this class on how to do that."
About specializing a class from some other class...
What you can do is something like this:
using System;
using System.Collections.Generic;
namespace ConsoleApp1
{
class Pet
{
protected string name;
public Pet(String name)
{
this.name = name;
}
}
class Dog : Pet
{
private List<String> tricks;
public Dog(String name, List<String> tricks):base(name)
{
this.tricks = tricks;
}
}
class Program
{
static void Main(string[] args)
{
List<string> tricks = new List<string>();
tricks.Add("sit");
tricks.Add("jump");
tricks.Add("bark");
Dog puppy = new Dog("Fido", tricks);
}
}
}
Dog inherits from Pet. Dog calls Pet's constructor at creation. Whatever name you pass into Dog constructor, it will forward it to Pet constructor.
Because what happens is that a subclass first calls the constructor of its superclass with the appropriate arguments. Then it runs its own constructor. Whatever is declared as public or protected in a class will be visible to its subclasses.
Therefore Dog will have name and also a list of tricks:
You achieve this kind of view with the "Locals" window.
I recommend that you read some tutorials on c# inheritance, interfaces and generics
I'm working on a small class library at work, and it naturally involves using generics for this task. But there is this thing that I don't really understand with generics:
Why would I need to use generic type parameters, and then constrain the the type parameter to a specific base class or interface.
Here's an example to what I mean:
public class MyGenericClass<T> where T : SomeBaseClass
{
private T data;
}
And here's the implementation without generics
public class MyClass
{
private SomeBaseClass data;
}
Are these two definitions the same (if yes, then i don't see the advatage of using generics here)?
If not, what do we benefit from using generics here?
As with almost all uses of generics, the benefit comes to the consumer. Constraining the type gives you the same advantages that you get by strongly typing your parameter (or you can do other things like ensure that there's a public parameterless constructor or ensure that it's either a value or reference type) while still retaining the niceties of generics for the consumer of your class or function.
Using generics also, for example, allows you to obtain the actual type that was specified, if that's of any particular value.
This example is a little contrived, but look at this:
public class BaseClass
{
public void FunctionYouNeed();
}
public class Derived : BaseClass
{
public void OtherFunction();
}
public class MyGenericClass<T> where T: BaseClass
{
public MyGenericClass(T wrappedValue)
{
WrappedValue = wrappedValue;
}
public T WrappedValue { get; set; }
public void Foo()
{
WrappedValue.FunctionYouNeed();
}
}
...
var MyGenericClass bar = new MyGenericClass<Derived>(new Derived());
bar.Foo();
bar.WrappedValue.OtherFunction();
The difference is that the former defines the new class as a specific type; the latter simply defines a plain class with a field of that type.
It's all about type safety. Using generics you can return a concrete type (T) instead of some base type which defines the API you need in your generic class. Therefore, the caller of your method won't have to cast the result to the concrete type (which is an error-prone operation).
The main difference is in usage. In the first case, the usage can have:
MyGenericClass<SomeDerivedClass> Variable
Variable.data.SomeDerivedProperty = X
And so that when you use that class, you can still access anything from SomeDerivedClass without casting back to it.
The second example will not allow this.
MyClass.data = SomeDerivedClassInstance
MyClass.data.SomeDerivedProperty = X //Compile Error
((SomeDerivedClass)MyClass.data).SomeDerivedProperty = X //Ewwwww
You will have to cast back up to the SomeDerivedClass (which is unsafe) to use something specific to the derived class.
I don't think that there is a huge amount of difference except that the generic version is constraining your Class, whereas the second is just a constraint on a member of the class. If you added more members and methods to your first Class, you would have the same constraint in place.