I would like to pass a generic interface to a function:
private I<T> CreateStubRepository<T, I >()
where I : aGenericBaseClass
So i was wondering if generic interfaces implement a base class or specific interface?
I know by using reflection you can test if it is a generic class but I dont see that helping me
Well. What's the point of forcing the usage of any interface? I really do not get it (or your question).
You should more likely do something like this:
public interface IMyRepository<T>
{
}
public class Repository<T> : IMyRepository<T>
{
}
private IMyRepository<TEntity> CreateStubRepository<TEntity>()
{
return new Repository<TEntity>();
}
var repos = CreateStubRepository<User>();
Update
thanks for your answer but thats not what I am asking. What I want to know is does a class that implements a generic interface have a base class or does it inherit from an interface? I dont want to force any interface its more a question of is the object passed generic
Classes do not inherit interfaces. They implement them. The different is subtle but important.
A class can only inherit another class. This means that if you do not specify that a class inherits from another it will still inherit from object. And that wont change no matter how many interfaces a class implement.
class MyClass : ICoolInterface // inherits object
class MyList : ArrayList, ISomeInterface // inherits ArrayList
class MyGenericList<T> : IList<T> // inherits object.
Generic or non-generic classes can implement or inherit from generic or non-generic interfaces and classes. The only limitation is that the full type of any interface/class implemented/inherited from must be discernible given the full type of the class doing the implementing or inheriting. For example, a Foo<Bar> might inherit from FooBase and implement IDisposable; a FnordDuffleBag might inherit from DuffleBag<Fnord> and implement IReachInto<Fnord>.
Thanks for all the comments I think i was going in the wrong direction, What I was hoping for was that when I applied to a class the framework would know that it inherited from a base class or interface of say aGenericItemBaseClass before it constructed the class at runtime.
Yes I know that I can create a generic class with type parameters and use that but thats not what I was asking (although you may have got that impression from my posting).
At runtime I know that when using reflection I can determine if a class is generic by calling : IsGenericType which returns true if a type is generic.
So what I wanted to know which may have been explained poorly is, when using template types is there anyway to determine if that type is a generic type? It appears the answer is No the IL interperates the class as generic not the compiler.
Related
I was browsing through Github when I noticed an interface in C# that had the following:
public interface IAction : IPrototype<IAction>
I have never seen this before. So I was curious what this exactly means or what it does and if this is applicable to things other than interfaces?
Is this a C# specific syntax for a specific behavior? (Is it useful in other OOP languages)
Sorry, if this is a really noob question but, I don't even know what this is called so I couldn't figure out exactly how to simply google it :P
That means that IAction inherits a generic IPrototype<T> interface where the type is IAction. IPrototype<T> may define a member to consume or produce a T, in this case it would be a IAction.
It's an interface that inherits from a generic interface.
To me this looks like an interface that enforces the prototype pattern by implementing the curiously recursive template pattern. More info can be found here https://zpbappi.com/curiously-recurring-template-pattern-in-csharp/.
Essentially, you are able to define an interface that contains methods that return or consume strongly typed instances of the implementor. Without the pattern the best you could do is return an instance of the base interface.
The prototype pattern is a pattern that allows for a class to be cloned, so I guess that the IPrototype interface has a method called Clone that returns T. In this case it would return IAction.
public interface IPrototype<T> where T : IPrototype<T>
{
// enforces a clone method returning the sub class
T Clone();
}
I have the following situation:
class Base<T>
class Derived : Base<Derived>
I know it is a bad practice that the base class knows who is the child class. I want to implement a Singleton base class, and for this, the base class must know who is the derived class, so please don't comment on this bad practice.
Is there a way to get the derived class type?
Getting the type using reflection is obviously problematic, because reflection is kind of static, and you can't cover the case of multiple derived classes.
EDIT: Maybe I wasn't clear enough. I meant that I want to be able to inherit the base class without specifiying the generic argument. It is a little stupid to pass yourself to the base class
Not sure what you are looking for, but code in base class knows its type when it is used as part of derived class:
class C1
{
public C1() { Console.WriteLine(this.GetType().Name);}
}
class C2: C1 { }
new C2(); // writes C2 from C1's constructor.
If you want the RuntimeType of T, use Type derivedType = typeof(T) from within Base<T>
I was wondering: can an interface inherit from another class?
I'm trying to let an interface inherit from the MarshalByRefObject.
My intent is that all classes implementing the interface also inherit from that class.
No, it cannot.
An interface can only specify other interfaces that must be implemented. This is done by using the same syntax as inheritance, but it's something different.
You could use an abstract class instead that inherits from MarshalByRefObject and and requires your interfaces to be implemented.
Depending on how you need to enforce your requirement, generic constraints might help, too. For generic type parameters, you can set class constraints, like class Argh<T> where T : MarshalByRefObject, ISomeInterface.
An interface cannot inherit from a class. In order to do that C# would need to support multiple inheritance of implementation which is currently not supported.
Imagine if you could derive an interface, IMyInterface, from a class, MyClass. Then when you come to declare another class that implements that interface, you would have to write something like:
public class MyImplementingClass: MyBaseClass, IMyInterface
But that implies multiple inheritance of implementation since you are inheriting from both MyBaseClass and MyClass.
No, but an interface can inherit from another interface.
No, an interface cannot have any implementation, so it can't inherit from a class. However you can make an abstract class that inherits from MarshalByRefObject.
No. Classes can implement interfaces. Its not the other way round.
Class can inherit class and implement interface.
Interface can implement only interface but can neither inherit nor implement classes.
I'm not familiar on using abstract class.
I'm trying to call a abstract class and get this error Cannot create an instance of the abstract class or interface and I already research this error but I'm really confused on this.
Here's my code:
string B1String;
while ((B1String = OasisFile.ReadLine()) != null)
{
Questions_Base oQuestions_Base = new Questions_Base(); // error here
oQuestions_Base.Import(B1String);
}
Please advice me.. thanks!
The purpose of an abstract class it to serve as part of a class hierarchy where more-derived classes share some common implementation.
If you have a flight simulator, you might define an abstract class ThingsThatFly that implements some properties (air speed, altitude, heading) and methods (TakeOff(), Land()) that all flying things have in common, but would be declared abstract because ThingsThatFly is an abstraction of all concrete things that fly. You could certainly have classes inbetween as well, for example Cessna172 could inherit from Airplane that inherits from ThingsThatFly. You would do that if all airplanes have some common implementation that e.g. birds don't have (for example, a Fuel Remaining property).
You would then have a number of concrete (= real life) things that fly like a Cessna 172, a Space Shuttle and a Duck. Each of those would be a concrete class that derives from ThingsThatFly
This is different than having the concrete classes implement an interface such as IThingsThatFly in that the abstract class provides not only a definition of the properties and methods that are expected, but also provides a (hopefully useful) implementation of those properties and methods.
An Abstract class can only be inherited.
public class CustomClass : Questions_Base {
}
Here's a link all about abstract classes and how to use them.
You cant create an instance of an abstract class.
You need to define a concrete class that inherits the abstract class, and create an instance of that.
Abstract class is made to be overriden by Derived class. If you have to have Abstract class, first create s Derived class from it and use Derived class contructor.
If it's not important, just remove abstract word from Questions_Base class declaration, so making that non abstract one. Also because in code provided I don't see any abstract member, so may this one is correct choice.
Regards.
An abstract class cannot be instantiated. You must provide an implementation for the class.
abstract class Animal
{
public abstract void Speak() { }
}
public class Dog : Animal
{
public override void Speak()
{
Console.WriteLine("Woof");
}
}
See MSDN on abstract for more information
From the documentation: "The abstract keyword enables you to create classes and class members that are incomplete and must be implemented in a derived class."
The purpose of using abstract is exactly to prevent instantiation, because you only created the class to use as a base class and never want an instance created.
More here.
An abstract class is one which MUST be inherited.
It falls somewhere between an Interface, which defines only the interface that a class must implement and no implementation code and a class that you can create an instance of which defines both the interface and the implementation code. There are several abstract classes in the .NET framework such as CollectionBase. You cannot create an instance of CollectionBase, it is intended for you to create a class that inherits from it and extends it's capabilities.
You should simpley be able to remove the kwy work "abstract" from your class definition of Questions_Base or create a new class definition that inherits from it.
Abstract classes, marked by the keyword abstract in the class definition, are typically used to define a base class in the hierarchy. What's special about them, is that you can't create an instance of them - if you try, you will get a compile error. Instead, you have to subclass them, as taught in the chapter on inheritance, and create an instance of your subclass. So when do you need an abstract class? It really depends on what you do. To be honest, you can go a long way without needing an abstract class, but they are great for specific things, like frameworks, which is why you will find quite a bit of abstract classes within the .NET framework it self. A good rule of thumb is that the name actually makes really good sense - abstract classes are very often, if not always, used to describe something abstract, something that is more of a concept than a real thing.
I am working on a class library and am having some trouble with generics. I have a ITransaction interface which has a collection of ITransactionItem. Each ITranscation can be either a CapitalCall or Distribution. A CapitalCall is a ITransaction but has a few additional properties. A CapitalCallItem is a ITransactionItem with a few additional properties. A CapitalCall has a collection of CapitalCallItems. Likewise, there exists a Distribution class with a collection of DistributionItem.
I have tried making the Transaction interface generic:
interface ITransactionBase<TItem>
where TItem: ITransactionItem
{
List<TItem> ITransactionItems
{
get;
set;
}
}
This works perfectly when I implement it:
class CapitalCall : ITransactionBase<CapitalCallItem>
Now all of the items in the collection are of type CapitalCallItem.
I run into the following problem. I would like to know the associate ITransaction on a ITranscationItem. I created a property on the ITransactionItem table of type ITranscation. When I use this property, it is no longer typed to the correct class:
var capitalCall = new CapitalCall();
var trans = capitalCall.TransactionItems[0].Transaction;
// trans is now of the base type ITransaction, instead of typed to CapitalCall.
I have tried making the ITransactionLineItem interface use generics as well, but I get into a recursive generic nightmare when I try to declare it. What is the correct way to model this?
Would this work:
interface ITransaction<TAction, TItems>
where TItems : ITransactionItem<TAction, TItems>
where TAction : ITransaction<TAction, TItems>
interface ITransactionItem<TAction, TItems>
where TItems : ITransactionItem<TAction, TItems>
where TAction : ITransaction<TAction, TItems>
I am confused as to how I could then use the interface by itself- what if I want a collection of mixed ITransactionItem, without specifying a type? Also I should add that I have base Transaction / Transaction item classes that implement the interface, and CapitalCall / Dist inherit from.
Yes, this sort of mutually recursive generic declaration will work, but it will make things very complicated - I know from experience. If you want an example of something similar, look at this declaration from my protocol buffers port:
public interface IMessage<TMessage, TBuilder> : IMessage<TMessage>
where TMessage : IMessage<TMessage, TBuilder>
where TBuilder : IBuilder<TMessage, TBuilder>
IBuilder<,> has the equivalent.
This declaration also demonstrates the answer to your last question: if some parts of your interface don't need to know the exact type of transaction, you can declare them in a "less generic" base interface. So you could have:
interface ITransaction<TAction, TItems> : ITransaction
where TItems : ITransactionItem<TAction, TItems>
where TAction : ITransaction<TAction, TItems>
for example, where ITransaction is a non-generic interface.
Again though, this is not for the faint of heart. In my case I can get away with it because almost no-one uses the raw interfaces - all the implementations are autogenerated, and client code uses those non-generic implementations. I would think long and hard before inflicting this on a developer to actually use day to day...
Yes the interfaces you wrote down should work as far as I can tell. Such "recursive" declarations work well with generics, but the question is whether you really need to make those generic in the first place? Recursive declarations are something which is not often used and may therefore be hard to grasp for other people using your classes.
As for using the interface for itself, you can still make a less generic interface and also implement it.