I am using a generic class called ViewModelCollection<BaseViewModel> which handles a lists of ViewModels and delivers standard add() and delete() commands.
Now I'm wondering if I can "extend" this class using the partial construct for a certain ViewModel, whose name is, say, CarViewModel.
Is something like this possible?
partial class ViewModelCollection<BaseViewModel>
{
... some command and list stuff ...
}
partial class ViewModelCollection<CarViewModel>
{
... special commands for car view model
}
No, you can't, partial just splits the class definition over multiple files, the definition has to be the same. You need to derive from ViewModelCollection<T>:
public class ViewModelCollection<T> where T: BaseViewModel
{
//methods
}
public class CarViewModelCollection : ViewModelCollection<CarVieModel>
{
//specific methods
}
partial is used only to split a class across multiple source files. The class definition itself must be the same.
Take the partial methods added and create an interface, you can then constrain the generic to use that interface and work off of those methods defined.
Related
I want to take a class I have and split it up into several little classes so it becomes easier to maintain and read. But this class that I try to split using partial is a static class.
I saw in an example on Stackoverflow that this was possible to do but when I do it, it keeps telling me that I cannot derive from a static class as static classes must derive from object.
So I have this setup:
public static class Facade
{
// A few general methods that other partial facades will use
}
public static partial class MachineFacade : Facade
{
// Methods that are specifically for Machine Queries in our Database
}
Any pointers? I want the Facade class to be static so that I don't have to initialize it before use.
Keep naming and modifiers consistent across files:
public static partial class Facade
{
// A few general methods that other partial facades will use
}
public static partial class Facade
{
// Methods that are specifically for Machine Queries in our Database
}
The problem is not that the class is a partial class. The problem is that you try to derive a static class from another one. There is no point in deriving a static class because you could not make use Polymorphism and other reasons for inheritance.
If you want to define a partial class, create the class with the same name and access modifier.
you do not need to override anything, just give them the same name:
public static partial class Facade
{
// this is the 1st part/file
}
public static partial class Facade
{
// this is the 2nd part/file
}
You can not inherit a static class.
Static classes are sealed and therefore cannot be inherited. They
cannot inherit from any class except Object.
C# doesn't support inheritance from a static class.
You have to choose between your classes being static:
public static class Facade
{
// A few general methods that other partial facades will use
}
public static partial class MachineFacade
{
// Methods that are specifically for Machine Queries in our Database
}
...or whether you wish MachineFacade to derive from Facade:
public class Facade
{
// A few general methods that other partial facades will use
}
public partial class MachineFacade : Facade
{
// Methods that are specifically for Machine Queries in our Database
}
Although I am too late for the party...
According to your problem description, I think your goals are:
Want a static method group.
Want a sub-group of it to be specialized for certain domain.
In this case, I would suggest using nested classes:
public static class Facade
{
// some methods
public static class Machine
{
// some other methods
}
}
Pros:
Methods are static. You can use them directly without initialize any instances.
The nested class names are used like namespaces. Readers of your code knows clearly that Facade.Machine methods are more specific than Facade ones and their target domain.
You can make methods with the same signature in different class level doing different things to mimic method overriding.
Cons:
There is no way to forbids users calling Facade.Machine methods when they should not.
No inheritance. Facade.Machine does not automatically have methods from Facade.
I'm not entirely sure about this. Is it 'static'?
The keyword you're looking for is partial.
https://msdn.microsoft.com/en-us/library/wa80x488.aspx
Yes partial is needed, but you also need abstract on the methods and the classes or it still won't compile because non-abstract methods must declare a body.
No It's not static. You need Partial Class. Also You need to provide body to your functions.
It is possible to split the definition of a class or a struct, an
interface or a method over two or more source files. Each source file
contains a section of the type or method definition, and all parts are
combined when the application is compiled.
To split a class definition, use the partial keyword modifier.
See Below example:
public partial class Employee
{
public void DoWork()
{
}
}
public partial class Employee
{
public void GoToLunch()
{
}
}
I have come to a point in my program where my polymorphism is broken. I realize that this is in my code, and I understand why; I'm just not sure how best to resolve it.
I have three model classes which have the same interface, but very significantly different implementations. I created an interface, and then three independent classes, which also derive from a ModelBase class:
public interface IMyModel
{ ... }
public class MyModelA : ModelBase, IMyModels
{ ... }
public class MyModelB : ModelBase, IMyModels
{ ... }
public class MyModelC : ModelBase, IMyModels
{ ... }
So far fine and dandy.
I have a ViewModel base class, which takes a model as a constructor:
public abstract class MyViewModelBase
{
public MyViewModelBase(ModelBase Model)
this.model = Model;
}
Now where I am caught; I want to have a concrete ViewModel class that can accept any of the three Model classes above:
public class MyViewModel : MyViewModelBase
{
MyViewModel(IMyModel Model) : base (Model) // <- Invalid Polymorphism!
{
// More here
}
}
This doesn't work, because it is possible for an implementation of IMyModel to not be based on ModelBase. The argument cannot be safely passed to the base constructor.
I can see one solution being to create an abstract base class derived from ModelBase for these models with exception-throwing content, and using that as the type in my ViewModel. I had started with a base class, but found that almost every part had some difference! However, that seems like a lot of work. Also, it won't ensure that derived classes implement everything (like an interface does). Finally, it seems to devalue the interface concept (indeed, I wouldn't need one anymore).
I don't see any way of marking the interface as saying that derived classes must have a specific base class. It would be nice if I could do this, but it's not allowed:
public interface IMyModel : MyModelBase
{ ... }
Is there a better way to do this?
Clarification:
I probably oversimplified the names here. I have other Models and ViewModels using the base classes, but not implementing the interface.
public class MyOtherModel : ModelBase // But not IMyModel!
{ ... }
public class MyOtherViewModel : MyViewModelBase
{
MyOtherViewModel(MyOtherModel Model) : base(Model) // This works
{ ... }
}
You could make your base class implement the interface, then inherit your implementation classes from the base class, marking the base class and methods as abstract (MustInherit/MustOverride in VB parlance). This would give you your polymorphism and guarantee the interface.
you could use generic constraints:
public class MyViewModel<T> : MyViewModelBase where T : IMyModel , ModelBase
{
MyViewModel(T model) : base (model) // T inherits ModelBase and implements IMyModel , so it is legal
{
// More here
}
}
Often (not always) when you find yourself building an Abstract Base Class it means you are trying to share both an interface and some common logic. Perhaps you can split these two things?
Move the common interface into IMyModels, and extract the common functionality into a separate class. Then include an instance of that helper class in each model. Essentially use composition to share functionality instead of inheritance.
Make ModelBase implement IMyModel. If ModelBase does not implement all methods of the interface, implement them as abstract methods.
To my understanding
Models are stupid Data containers
Interfaces describe behaviour and Functionality, not data.
So why bother putting interfaces on the models at all?
#Yochai : Good point, using Generics - saves code, but you must first declare base classes (only one per class, there's no mixed inheritance in C#), then any amount of interfaces, thus your code should be:
public class MyViewModel<T> : MyViewModelBase where T : ModelBase, IMyModel
I am having one class called BaseClass which contains some logic applicable to whole web site.
In order to create a strongly typed view we need to inherit the page from System.Web.Mvc.ViewPage generic class. But In our case I have to Inherit the BaseClass from
System.Web.Mvc.ViewPage to apply some common settings, but the BaseClass should be inherited from System.Web.Mvc.ViewPage<> generic version. But I cannot inherit the BaseClass from System.Web.Mvc.ViewPage<> as it will change other class also. So I created one more class of type BaseClass<> inheriting it from System.Web.Mvc.ViewPage<> and copied the whole code of BaseClass in BaseClass<>. But the code in BaseClass is controlled by other team so it will be changed frequently so my BaseClass<> should be in sync with BaseClass. Please help me in eliminating the code duplication or any other approach to make strongly typed View.
Thanks
Ashwani
Ok... it seems like you can't change the use of this BaseClass for your views.
How about duplicating the logic of ViewPage<TModel>? Have a look at the ViewPage`1.cs file that is in the asp.net mvc source code and duplicate that. That would be the easiest way...
E.g.
public class BaseClass : ViewPage
{
//Custom logic for africa here
}
public class BaseClass<TModel> : BaseClass
{
//Copy and paste all the code from ViewPage`1.cs
//It's not much - about 50 lines.
}
HTHs,
Charles
Ps. The link to the source code is for asp.net mvc 2
Ouch...
I am not sure what you are having in your BaseClass. But I think the best option is to create a BaseViewModel (maybe your BaseClass is you BaseViewModel> and then create specific ViewModels (which inherits from BaseViewModel) for each page.
For example your ViewModels should look something like this:
public abstract class BaseViewModel
{
public string SiteTitle {get;set;}
public int SomeProperty{get;set;}
}
public class UserViewModel: BaseViewModel
{
public string UserName{get;set;}
public string Email{get;set;}
}
and you should create strongly typed view like this:
System.Web.Mvc.ViewPage<UserViewModel>
You can take a look at AutoMapper to simplyfy the mapping process from your custom classes to ViewModels.
Cheers
public abstract class MyBaseView<T> : ViewPage<T>
{
//common logic here
}
public class UserView: MyBaseView<MyUserInfo>
{}
somthing like
public partial class RegistrationForm :
IRegistrationForm, System.Web.UI.UserControl
but this example does not work.
Yes, but you do it like this:
public partial class RegistrationForm : System.Web.UI.UserControl, IRegistrationForm
C# doesn't support multiple inheritance, so you put the class you inherit from first, followed by a comma, followed by a comma-delimited list of the interfaces it implements.
Absolutely, a class can inherit from a single base class and implement any number of interfaces at the same time.
Your example does not work because the one base class must be listed first, before all the interfaces...