Inheriting generic can't up cast - c#

I have a problem with inheriting a custom generic. The compiler (Visual Studio for Mac), complaints that the inheriting generic can't be implicitly converted to another, inheriting type. A break down of my code is as follows:
I have an interface called IAnsweredCommon and another interface that inherits from it called IAnsweredAndroid
public interface IAnsweredCommon
and
public interface IAnsweredAndroid : IAnsweredCommon
I have two other classes that use these interfaces.
public abstract class ConstructorCommon<AnsweredType> where AnsweredType : IAnsweredCommon
and
public class ConstructorAndroid : ConstructorCommon<IAnsweredAndroid>
This works. The common constructor has a member variable of AnsweredType allowing it to treat it as IAnsweredCommon and run OS agnostic code against it, while allowing the Android constructor access to the same member variable and can treat it as IAnsweredAndroid allowing the Android constructor to run Android specific code against it. The Android constructor can handle Android specific things while passing OS agnostic code to the common constructor. This works and is what I want as it allows me to extend this to iOS.
Now the problem is that I have another layer on top of the constructor. The constructor basically implements the builder design pattern and so it has lots of methods to call in order to construct an answered object. I have director classes that call predetermined constructor methods to create a predetermined answered object.
public abstract class DirectorCommon<AnsweredConstructorType>
where AnsweredConstructorType : ConstructorCommon<IAnsweredCommon>
and
public class DirectorAndroid : DirectorCommon<ConstructorAndroid>
The compiler complains about being unable to implicitly convert ConstructorAndroid to ConstructorCommon<\IAnsweredCommon>. I've expanded upon ConstructorAndroid for testing purposes and I've temporary changed it to be:
public class DirectorAndroid : DirectorCommon<ConstructorCommon<IAnsweredAndroid>>
Now, if I change the IAnsweredAndroid interface to IAnsweredCommon, the error goes away (as it should since it exactly matches the constraint). But if I change it to IAnsweredAndroid, I get the error. I'm confused as IAnsweredAndroid IS IAnsweredCommon (inheritance) and therefore, the compiler should be able to upcast IAnsweredAndroid to IAnsweredCommon. After all it's doing this in the constructor classes.
NOTE: I've cleaned up the code to make it easier to read (removed namespaces, irrelevant code and what-not) so the code maybe not be 'runnable', but regardless, please point out any errors and I'm sure it's a minor thing I'm missing and you never know if an error is because of the clean up or if it's an actual error.

That is not possible, class<A> is not assignable to class<B>, also if A derives from B or vice versa.
It would work, if ConstructorCommon would be an interface, IConstructorCommon, and be defined as:
interface IConstructorCommon<out AnsweredType> where AnsweredType : IAnsweredCommon
The "out" makes it covariant.
To replace an abstract base-type with an interface, might be suitable.`
Your error has nothing to do with the constraint, the way you found just matches, cause the type matches. You can assign a ConstructorComman<Android> to ConstructorCommon<Android> but not to ConstructorCommon<Answer> no matter if there is a constraint or not. Constraints you need only if you want to call special methods, that only your constrained-type has.

Related

How Can I have abstract parameters in method?

Basiclly I have a class like Individual and another class that inherits from it - IndividualForSomeAnotherWork.
I have a class called Population too and methods like Add(Individual individual).
Can I pass the IndividualForSomeAnotherWork to Add method through Individual type? Or should I use interface or abstract class? I'm asking because I'm getting NullReferenceException all the time.
EDIT:
Sorry for not answering so long. My problem was not initializing a List containing objects so I couldn't add to it. But I also wanted to know that can I pass arguments as I said earlier. Thanks for answers.
I would recommend an IIndividual type of interface. In this case, if you have:
abstract class Individual : IIndividual {
}
class IndividualForSomeOtherWork : Individual {
}
... then Population.Add(IIndividual Individual) will accept the base class Individual as well as any descendants of Individual.
Think of the interface as a contract with the Population class that any individual within it's collection will have implemented all the functions it requires of the individual.
Note that the abstract Individual is not required to implement all functions defined within the interface. If the interface requires:
interface IIndividual {
void DoWork();
}
... then the base Individual is not knowledgeable of what specialized work an IndividualForSomeOtherWork will actually perform. So in the abstract class:
abstract void DoWork();
This function must be defined within the specialized individual descendants.
Yes, you can pass an IndividualForSomeAnotherWork to Add(Individual individual). It should work correctly. Your error is due to something else. Try debugging it yourself, or post more details and code and we might be able to help.
In terms of what you are trying to do here, an abstract class is not fundamentally different from an interface. In both cases it's not possible to have a argument whose type exactly matches the type of the formal parameter. See DrawImage for an explicit example of this (Image is an abstract class).
The NullReferenceException you are seeing is not directly related to the parameter type being abstract.

Cannot specify both a constraint class and the 'class' or 'struct' constraint

I am trying to work around a mocking issue by creating a custom mock of IDbSet.
The custom mock:
public class DbSetMock : IDbSet<Tenant>
{
/* hidden all other implemented methods/properties */
public TDerivedEntity Create<TDerivedEntity>() where TDerivedEntity : class, Tenant
{
throw new NotImplementedException();
}
}
The create method gives a build error that I have no clue on how to solve:
cannot specify both a constraint class and the 'class' or 'struct' constraint
Simply removing class from the constraints results in another build error (which I also don't understand :( ).
The constraints for type parameter 'TDerivedEntity' of method 'Tests.DAL.Tenants.DbSetMock.Create<TDerivedEntity>()' must match the constraints for type parameter 'TDerivedEntity' of interface method 'System.Data.Entity.IDbSet<BusinessLayer.DAL.Tenants.Tenant>.Create<TDerivedEntity>()'. Consider using an explicit interface implementation instead.
Can anybody help me successfully building this class?
Since the TDerived type parameter is constrained to be a Tenant, adding the constraints class or struct is redundant. Just remove the class constraint.
UPDATE: Curiously there seems to be a conflict between the compiler errors here. If you "fix" one you get the other, in an infinite loop of despair. Luckily, the second error also gives us a way out: you can use an explicit interface implementation:
public class DbSetMock : IDbSet<Tenant>
{
TDerivedEntity IDbSet<Tenant>.Create<TDerivedEntity>()
{
throw new NotImplementedException();
}
}
There seems to be no way to implement that method without using explicit interface implementation. If you need it as part of the public interface of the class, I suggest creating another method that the interface implementation forwards to:
public class DbSetMock : IDbSet<Tenant>
{
TDerivedEntity IDbSet<Tenant>.Create<TDerivedEntity>()
{
return Create<TDerivedEntity>();
}
public TDerivedEntity Create<TDerivedEntity>() where TDerivedEntity : Tenant
{
throw new NotImplementedException();
}
}
Try to remove class from method part, like this;
public class DbSetMock : IDbSet<Tenant>
{
/* hidden all other implemented methods/properties */
public TDerivedEntity Create<TDerivedEntity>() where TDerivedEntity : Tenant
{
throw new NotImplementedException();
}
}
class, Tenant is redundant code.
There are presently only three inheritable classes in the Framework whose descendants may be value types: Object, ValueType, and Enum. All three of those types are class types, but any type derived from ValueType or Enum will be a value type, and any type derived from Object which is not derived from ValueType will be a class type. With any type other than the above, a class or struct constraint would either be redundant or contradictory; not coincidentally, C# disallows constraints to be directly specified for the above types.
In some languages and frameworks, a prevailing design philosophy is that if there is a particular form of expression where the behavior that applies to that general form would be useless, there's no reason for the language/framework designer to go out of the way to forbid such a form. Under such a philosophy, it would be perfectly legal to have a generic type constrained to a sealed type (e.g. Fnord). Such a thing would be pointless if the type in question were sealed and no future version would ever be otherwise, but since applying the normal interpretation of generic constraints to such situation would yield reasonable behavior, and since there might conceivably be some situations where such constraints might be useful (e.g. writing code to use a class which is in development and is presently sealed, but may or may not be sealed in its final release, or writing code to interface with Reflection-based code that expects particular generic forms), the philosophy would suggest that constraining a generic type to a sealed class should be legal.
In some other languages and frameworks, a differing philosophy holds: if a programmer might expect some particular form of a construct to offer features beyond the general form but it does not, and if that particular form wouldn't seem very useful without such features, the language should forbid it, even if the construct would have a precise meaning which was well-defined and could not be expressed via other means if the implementers of the language don't see a reason for programmers to want to express that actual meaning.
The fact that neither C# nor .net has any problem with having one type parameter constrained to another, even when that other parameter is of a type that would not be accepted as a constraint, suggests that the restriction is artificially imposed by the language due to the aforementioned philosophy. It's unfortunate, IMHO, since there are many situations where it would be helpful to be able to say, e.g.
bool HasAnyFlags<T>(this T enum1, T enum2) where T:struct,System.Enum
and even though .net would usefully allow such a construct, and even though the only obstacle which prevents C# from excepting it code to explicitly looks for such constraints so as to disallow them, the C# designers decided to forbid such constructs rather than allow them to behave as .net would interpret them (meaning that HasAnyFlags couldn't do anything directly with a T that it couldn't do with System.Enum, and using a T as a System.Enum would generally be no faster than using a System.Enum (sometimes slower), but T could nonetheless be useful for a couple reasons:
The method could enforce at compile time that the parameters must be the *same* enumerated type
The method could use a static class `EnumEvaluator` to generate and cache static delegates of type `Func`, such that `HasAnyFlags(T enum1, T enum2)` could be implemented as `return EnumEvaluator.HasAnyFlags(enum1,enum2);`. Such a function could be more than ten times as fast as `Enum.HasFlag`.
Still, useful as it might be to specify such constraints, the only way to specify them in C# is to have the C# source code specify some dummy type which could be used as a constraint, and then run the compiled code through a utility which will replace all references to the dummy type with references to the type one wanted to use in the first place.
It is telling you is that the constraint:
class, Tenant
is redundant. You can just remove class since Tenant is more constrained than class and includes class.

Interface is forceing abstract class to implement its functions

I have got a abstract class which is implementing 3 interfaces.
public abstract class ServiceBaseCore<Entity, EntityKey> : MarshalByRefObject, IComponentService, IEntityProvider<Entity, EntityKey>
where Entity : IEntityId<EntityKey>, new()
where EntityKey : IEntityKey, new()
{
// Provided functionality/body to some methods of interface
}
Problem: i am getting error that my abstract class is not providing implementation (definition/body) to functions of interface, where as what i read is that "if a class is abstract than there is no need to provide body to all/any functions of interface its implementing".
Note: the code was generated by codeSmith even though its showing error.
please tell me where i am wrong and what i am missing.
Thanks
Just create some abstract functions, and the compiler will stop complaining:
public abstract void MyMethodDeclaredInTheInterface();
EDIT: To speed up the process, just move the caret on the interface name in your abstract class, then ctrl + . and select "Implement interface YourInterface".
Then a little search and replace over the NotImplementedException should do the trick.
Create abstract methods for the interface. Otherwise, the class doesn't actually necessarily implement those methods in any way, even though derived classes might (the derived versions wouldn't be available to the base via vtables and therefore could not fulfill the interface contract). That would violate the idea behind interfaces.
Note: it's late and I'm tired, so I might be wrong about the rationale. But adding abstract methods for the methods required by the interfaces will take care of the problem.
You should be able to right click on the Interface name (near MyClass : IMyInterface) to see the context menu, and then choose 'Implement Interface'. Visual Studio will create all the required methods and properties to satsify the interface.
You may try some IDE to save much of your time. I know exactly, that Eclipse can do this automatically.

Why do we need to have Object class as baseclass for all the classes?

Either in C# or Java or in any other language which follows oops concepts generally has 'Object' as super class for it by default. Why do we need to have Object as base class for all the classes we create?
When multiple inheritance is not possible in a language such as C# or Java how can we derive our class from another class when it is already derived from Object class. This question may look like silly but wanted to know some experts opinions on it.
Having a single-rooted type hierarchy can be handy in various ways. In particular, before generics came along, it was the only way that something like ArrayList would work. With generics, there's significantly less advantage to it - although it could still be useful in some situations, I suspect. EDIT: As an example, LINQ to XML's construction model is very "loose" in terms of being specified via object... but it works really well.
As for deriving from different classes - you derive directly from one class, but that will in turn derive indirectly from another one, and so on up to Object.
Note that the things which "all objects have in common" such as hash code, equality and monitors count as another design decision which I would question the wisdom of. Without a single rooted hierarchy these design decisions possibly wouldn't have been made the same way ;)
The fact that every class inherits object ensured by the compiler.
Meaning that is you write:
class A {}
It will compile like:
class A : Object{}
But if you state:
class B : A {}
Object will be in the hierarchy of B but not directly - so there is still no multiple inheritance.
In short
1) The Object class defines the basic state and behavior that all objects must have, such as the ability to compare oneself to another object, to convert to a string, to wait on a condition variable, to notify other objects that a condition variable has changed, and to return the object's class.
2) You can have B extend C, and A extend B. A is the child class of B, and B is the child class of C. Naturally, A is also a child class of C.
Well, the multiple inheritance of Object does not apply - you can think of it as:
"If a type doesn't have a base type, then implicitly inject Object".
Thus, applying the rule ad-nauseam, all types inherit from object once and once only - since at the bottom of the hierarchy must be a type that has no base; and therefore which will implicitly inherit from Object.
As for why these languages/frameworks have this as a feature, I have a few reasons:
1) The clue's in the name 'Object Oriented'. Everything is an object, therefore everything should have 'Object' (or equivalent) at it's core otherwise the design principle would be broken from the get-go.
2) Allows the framework to provide hooks for common operations that all types should/might need to support. Such as hash-code generation, string output for debugging etc etc.
3) It means that you can avoid resorting to nasty type casts that can break stuff - like (((int *)(void*))value) - since you have a nice friendly supertype for everything
There's probably loads more than this - and in the time it's taken me to write this 6 new answers have been posted; so I'll leave it there and hope that better people than I can explain in more detail and perhaps better :)
Regarding the first part of your question, it's how classes receive common properties and methods. It's also how we can have strongly-typed parameters to functions that can accept any object.
Regarding your second question, you simply derive your class from the other class; it will then be a descendant of that class, which is in turn a descendant of Object. There's no conflict.
You have the Object base class because amongst others because the Object class has methods (like, in .NET, GetHashCode(), which contain common functionality every object should have).
Multiple inheritance is indeed not possible, but it is possible to derive class A from class B, because A may not directly derive from Object, but B does, so all classes ultimately derive from Object, if you go far enough in the class' inheritance hierarchy.
Just to compare, let's take a look at a language that doesn't enforce a single root class - Objective-C. In most Objective-C environments there will be three root classes available (Object, NSObject and NSProxy), and you can write your own root class by just not declaring a superclass. In fact Object is deprecated and only exists for legacy reasons, but it's informative to include it in this discussion. The language is duck typed, so you can declare a variable's type as "any old object" (written as id), then it doesn't even matter what root class it has.
OK, so we've got all of these base classes. In fact, even for the compiler and runtime libraries to be able to get anywhere they need some common behaviour: the root classes must all have a pointer ivar called isa that references a class definition structure. Without that pointer, the compiler doesn't know how to create an object structure, and the runtime library won't know how to find out what class an object is, what its instance variables are, what messages it responds to and so forth.
So even though Objective-C claims to have multiple root classes, in fact there's some behaviour that all objects must implement. So in all but name, there's really a common primitive superclass, albeit one with less API than java.lang.Object.
N.B. as it happens both NSObject and NSProxy do provide a rich API similar to java.lang.Object, via a protocol (like a Java interface). Most API that claims to deal with the id type (remember, that's the "any old object" type) will actually assume it responds to messages in the protocol. By the time you actually need to use an object, rather than just create it with a compiler, it turns out to be useful to fold all of this common behaviour like equality, hashing, string descriptions etc. into the root class.
Well multiple inheritance is a totally different ball game.
An example of multiple inheritance:-
class Root
{
public abstract void Test();
}
class leftChild : Root
{
public override void Test()
{
}
}
class rightChild : Root
{
public override void Test()
{
}
}
class leafChild : rightChild, leftChild
{
}
The problem here being leafChild inherits Test of rightChild and leftChild. So a case of conflicting methods. This is called a diamond problem.
But when you use the object as super class the hierarchy goes like this:-
class Object
{
public abstract void hashcode();
//other methods
}
class leftChild : Object
{
public override void hashcode()
{
}
}
class rightChild : Object
{
public override void hashcode()
{
}
}
So here we derive both classes from Object but that's the end of it.
It acts like a template for all the objects which will derive from it, so that some common functionality required by every object is provided by default. For example cloning, hashcode and object locking etc.

Why is a base class in C# allowed to implement an interface contract without inheriting from it?

I've stumbled upon this "feature" of C# - the base class that implements interface methods does not have to derive from it.
Example:
public interface IContract
{
void Func();
}
// Note that Base does **not** derive from IContract
public abstract class Base
{
public void Func()
{
Console.WriteLine("Base.Func");
}
}
// Note that Derived does *not* provide implementation for IContract
public class Derived : Base, IContract
{
}
What happens is that Derived magically picks-up a public method, Base.Func, and decides that it will implement IContract.Func.
What is the reason behind this magic?
IMHO: this "quasi-implementation" feature is very-unintuitive and make code-inspection much harder. What do you think?
The reason is that your comment is simply incorrect:
// Note that Derived does not provide implementation for IContract
Sure it does. Follow the logic through.
Derived is required to provide a public member corresponding to each member of IContract.
All inheritable members of a base class are also members of a derived class; that's the definition of inheritance.
Therefore Derived provides an implementation for IContract; its inherited member is a member that fulfills the requirement
Therefore, no error.
this feature is very-unintuitive and make code-inspection much harder. What do you think?
I think you shouldn't use the feature if you don't like it. If you find it confusing and weird to read code that uses this feature then encourage your coworkers who use this feature to stop doing so.
How is this feature different from any other feature where a method from a base class is used from a derived class? There are a number of different ways in which a method from a base class may be used or mentioned in a derived class -- method calls, overrides, method group conversions, and so on.
Furthermore, this is relatively speaking a simple, straightforward case. If you really want to complain about confusing interface semantics in C#, I'd spend my time complaining about interface reimplementation semantics. That's the one that really seems to bake people's noodles. I always have to look that thing up in the spec to make sure I'm getting the semantics right.
Why do you think that this is strange and unnatural? Every public member of base class is also a public member of derived class. So there is no contradiction here. Anyhow you can implement interface explicitely if you like.

Categories

Resources