Generic class is base class, and a member method uses generic data type, how will you make the method of derived accept integers instead of generic data type?
You can do something like this -
public class MyBaseClass<T>
{
public virtual void MyMethod(T typeT)
{
//some important functionality
}
}
public class MyChildClass : MyBaseClass<int>
{
public override void MyMethod(int typeInt)
{
//Do your stuff
//and if you would like to call base method, use the following-
base.MyMethod(typevar);
}
}
Related
I have a base class (can also be an interface) and n-classes that extend the base class.
I want to have a function that excepts only classes of the base class type.
Currently I am doing something like this
abstract class BaseClass{
public abstract void Execute();
}
class MyClass : BaseClass {
public void Execute(){
//my code
}
}
[...]
MyFunction(Type param)
{
//check if param is type of BaseClass. If not, throw exception
}
The problem with this implementation is, that I can pass any type of class. My goal is to prevent this.
Like in TypeScript you can do this
myFunction(param: {new (): BaseClass}){
//my code
}
Is there a similar approach I can use in C#?
There's a couple of things you can do, depending on what you actually want to do in the function.
Stating your actual use case makes it easier to come up with a solution.
Looking at the typescript code it looks like you want to be able to call the constructor inside the function to produce an instance of the given type that derives from BaseClass.
In this case I'd try using generics:
public void MyFunction<T>() where T: BaseClass, new()
{
T myClass = new T();
//Do stuff...
}
This works with interfaces/classes. It will only accept types deriving from BaseClass.
Edit: updated my answer after being notified how my previous answer wouldn't know if it was a grandchild of the base class
public abstract class BaseClass
{
public abstract void Test();
}
public class DerivedFromBase : BaseClass
{
public override void Test(){}
}
public class Grandchild : DerivedFromBase
{
}
public class Main
{
Grandchild aClass= new Grandchild(); // Instantiate Normally
UseIfOnlyTypeOfBaseClass(aClass);// Use Method with check like this
}
private void UseIfOnlyTypeOfBaseClass<T>(T param)
{
if (typeof(T).IsSubclassOf(typeof(BaseClass)))
{
Console.WriteLine("Match");
}
}
My abstract class has a method that is abstract like this:
public abstract void Run(BaseType baseType);
And now in my derived class which has to implement this function, i want it to only accept a specific derived type from BaseType
So it would have:
public override void Run(DerivedType derivedType){}
Is there any way to enforce this at all ?
Currently i have to do:
public override void Run(BaseType baseType) {
if(!(baseType is DerivedType)) {
// throw exception
}
}
It's not very strict with enforcing the type - i was wondering if there is a way to do so without the need to constantly add a type check ?
I've sometimes used this pattern:
public interface IHandler
{
void Run();
}
public abstract class BaseHandler<TObj> : IHandler
where TObj: BaseType
{
protected readonly TObj _obj {get;set;}
public BaseHandler(TObj obj)
{
this._obj = obj;
}
public abstract void Run();
}
public class DerivedHandler : BaseHandler<DerivedType>
{
public DerivedHandler(DerivedType obj) : base(obj)
{
}
public override void Run()
{
// do stuff with base._obj
}
}
public class HandlerService
{
public IHandler CreateHandler<TObj>(TObj obj)
{
// Depending on your DI container, you could resolve this automatically from the container
if (typeof(TObj) == typeof(DerivedType))
{
return new DerivedHandler(obj);
}
throw new NotImplementedException();
}
}
This allows you to define a specific "handler" for each derived type, and then access it through a common interface.
The idea is that you instantiate a specific handler for the object, and then methods like Run() operate on that object. You can then resolve a handler through the service.
I'll fill in some more info later when I have time.
You want the language to do something that it really shouldn't. You want a covariant argument, which violates the Liskov Substitution Principle: It makes the implementation of the abstract class not usable in every situation where the abstract base class is usable. This is the whole point of abstract base classes to begin with.
Although it could make sense to have a covariant return type (returning a more derived type then the abstract methods specifies) the language also prevents you to do that.
I have the following "models":
My base class:
public abstract class Search : Model
{
//Properties ...
public void ShallowCopy(Search reference)
{
base.ShallowCopy(reference);
//Do stuff
}
}
My inheriting class:
public class Vehicle : Search
{
//Properties
public void ShallowCopy(Vehicle reference)
{
base.ShallowCopy(reference);
//Do stuff
}
}
My base "viewModel" is generic:
public abstract class MasterDataWithoutAddressViewModel<TPrimaryModel> : MasterDataViewModel<TPrimaryModel>
where TPrimaryModel : Search, new()
{
public void JustAMethod()
{
//do stuff
foreach (TPrimaryModel primaryModel in primaryModels)
{
TPrimaryModel primaryModelCopy = new TPrimaryModel();
primaryModelCopy.ShallowCopy(primaryModel);
//Do more stuff
}
}
}
My inheriting "viewModel":
public class VehicleViewModel : MasterDataWithoutAddressViewModel<Vehicle>
{
//...
}
With primaryModelCopy.ShallowCopy(primaryModel); I expected the ShallowCopy of Vehicle to be called. However just the method of the base class Search is called. Debugger shows that primaryModel and primaryModelCopy are both from the correct type (Vehicle).
This is the complete inheritance hierarchy of my "models":
This happens because you have a compile time collision (due to the way overload resolution behaves) between methods with the same signature in your base and derived classes.
You need to declare your method virtual, and override them in derived classes:
Base:
public virtual void ShallowCopy(Search reference)
{
base.ShallowCopy(reference);
//Do stuff
}
Derived:
public override void ShallowCopy(Search reference)
{
base.ShallowCopy(reference);
//Do stuff
}
Overload resolution is performed at compile-time, and in JustAMethod it's performed once, not once per type-argument. So primaryModelCopy.ShallowCopy is resolved to the Search.ShallowCopy method.
There are two options here:
You could use normal polymorphism, making Search.ShallowCopy virtual, and overriding it in Vehicle.ShallowCopy (which would need to cast the parameter back to Vehicle in the method)
You could use dynamic typing in JustAMethod to perform overload resolution at execution-time instead. (This doesn't feel like a good idea to me, but it's an option.)
Is it possible to instruct a construct in C# to forcefully call an implementing method?
I've created an interface that forces implementing classes to implement a method. Now I want this method to be called by all constructors of implementing classes.
I know I can create a base class and call the method in its constructor, but I cannot force every child class to call the base class constructor?
No, Abstract class will be your workaround.
public abstract class MyAbstract : IMyInterface
{
public MyAbstract()
{
MyMustCallmethod();
}
public abstract void MyInterfaceMember();//Let derived classes implement your interface
private void MyMustCallmethod()
{
//implementation
}
}
When you call the constructor to an inheriting class (say B inheriting from A), the constructor for the inherited class will be also called. So if you want to make sure that all classes inheriting from A call the Foo method you can set the call in the A constructor:
public class A {
public A() {
Foo();
}
public void Foo() {/* something here */}
}
public class B: A {
public B(string param) {/* A constructor will be called */}
}
poke comment below explains that the default constructor is selected. If no default constructor exists you must call a constructor explicitly.
But you cannot force an interface method to be called because interfaces contain no implementation. Using the above code will mean that only the A class will implement the interface. So in order to ensure that inheriting classes call the method and must define it explicitly i use something like this:
public interface IHasFooThatMustBeCalledInConstructor {
void Foo();
}
public abstract class A: IHasFooThatMustBeCalledInConstructor {
public A() {
Foo();
}
public abstract void Foo();
}
public class B: A {
public B(string param) {}
public void Foo() { };
}
I have a generic class I have created as so:
public abstract class MyClass<T>
{
public T Model
{
get;
protected set;
}
}
And at some point in my code I want to do something with anything of MyClass type. Something like:
private void MyMethod(object param)
{
myClassVar = param as MyClass;
param.Model....etc
}
Is this possible? Or do I need to make MyClass be a subclass of something (MyClassBase) or implement an interface (IMyClass)?
I believe what you are need is to make MyMethod method generic and add constraint on its type parameter:
interface IMyInterface
{
void Foobar();
}
class MyClass<T>
{
public T Model
{
get;
protected set;
}
}
private void MyMethod<T>(MyClass<T> param) where T : IMyInterface
{
param.Model.Foobar();
}
No.
You need to inherit a non-generic base class or implement a non-generic interface.
Note that you won't be able to use the Model property, since it cannot have a type (unless you constrain it to a base type and implement an untyped property explicitly).
Yes, you need. If type of generic class is undefined you need to create generic interface or using base-class...