public interface IBase
{
int Id { get; set; }
}
public interface IDerivedA : IBase
{
int Name { get; set; }
int Quantity { get; set; }
}
public interface IDerivedB : IBase
{
string Name { get; set; }
IEnumerable<IDerivedA> DerivedBs { get; set; }
}
And here is an implementation for a class which will be serialized, but I'm getting compilation error when I try to use DerivedASerialize class which is a derived class from IDerivedA interface
[MessagePack.Union(0, typeof(DerivedASerialize))]
[MessagePack.Union(1, typeof(DerivedBSerialize))]
[MessagePack.MessagePackObject(true)]
public class BaseSerialize : IBase
{
public int Id { get; set; }
public bool IsNull { get;set; }
}
[MessagePack.MessagePackObject(true)]
public class DerivedASerialize : BaseSerialize, IDerivedA
{
public int Name { get; set; }
public int Quantity { get; set; }
}
[MessagePack.MessagePackObject(true)]
public class DerivedBSerialize : BaseSerialize, IDerivedB
{
public string Name { get; set; }
public IEnumerable<DerivedASerialize> DerivedBs { get; set; }
}
Is there any work around? as I can only serialize classes.
And I would like to have another class which also derive from the same interface and have different properties
Using neuec's MessagePack.
Edit: Add serialization logic to classes.
If you require two different "Name" fields you can use explicit interface implementation:
public class DerivedBSerialize : BaseSerialize, IDerivedB
{
public string Name { get; set; }
public IEnumerable<DerivedASerialize> DerivedBs { get; set; }
string IDerivedB.Name { get; set; }
IEnumerable<IDerivedA> IDerivedB.DerivedBs { get; set; }
}
If you require just a single "Name" field - you can raise it to "IBase", or create another interface -
interface INameable { string Name {get; set;} }
Related
<I have two classes with too many fields . which are basically the Model of MVC . I want to create a third class which take few fields from both 1st,2nd by inheritance but not all the fields of 1st and 2nd class is it possible by inheritance .I want to
make a new class without declare field in it
public class OpeningBalanceLiteModel
{
public Int64 LedgerId { get; set; }
public String LedgerCode { get; set; }
public Int64? ParentLedgerId { get; set; }
public Decimal OpeningBalance { get; set; }
public Boolean? Status { get; set; }
public Int32? LedgerCategoryId { get; set; }
public Byte Is_Active { get; set; }
public Byte Is_Deleted { get; set; }
}
public class DrCrDetailLiteModel
{
public Int32 Id { get; set; }
public Int32 TransactionTypeId { get; set; }
public Int32? AmountType { get; set; }
public Decimal? Amount { get; set; }
public String VoucherNarration { get; set; }
public Int32 FinancialYearId { get; set; }
public Int64 CompanyId { get; set; }
public Decimal? SubsidiaryId { get; set; }
public Decimal? LocationBranchId { get; set; }
public Decimal? DivisionId { get; set; }
public Int32? DepartmentId { get; set; }
public Int32? ProjectId { get; set; }
public Int32? ProjectEstimationId { get; set; }
public Boolean? IsAdvancePayment { get; set; }
public Boolean? IsHiddenFromSourceLedger { get; set; }
public Boolean? IsReversed { get; set; }
}
public class OpeningBalanceDrCrMurg
{
}```
* i wan to add 3 fields of both class by inheritance
We commonly calls inheritance a "is a" relation ship, an apple is a fruit. If you do not include all properties it is not a "is a" relationship. Is all fruits have a color, then an apple must have a color.
Moreover, c# does not support multiple inheritance. You could inherit from multiple interfaces, and that would also allow you to use explicit interface implementation to hide properties unless a reference of the interface type is used. But I get the impression that your goal is implementation inheritance.
My recommendation would be to use Composition instead of inheritance. Group your properties in to logical groups, and compose these models, for example:
public class LedgerModel{
public Int64 LedgerId { get; set; }
public String LedgerCode { get; set; }
public Int64? ParentLedgerId { get; set; }
}
public class OpeningBalanceLiteModel{
LedgerModel {get;set;}
...
}
That should allow finer grained control to allow you to include any combination of property-groups in your classes.
you should create a Base Class ex:
public class BaseClass
{
public int Id1 { get; set; }
public int Id2 { get; set; }
public int Id3 { get; set; }
}
public class childrenClass1 :BaseClass
{
...
}
public class childrenClass2:BaseClass
{
...
}
Now children class1 and 2 have Id1/Id2/Id3
In my CollectionService class i want to be able to use either DatabaseWatchService or RemoteFilesWatchService therefore I used IWatchService<IEntity> watchService parameter which should be common for both. Nevertheless in DoIt() when i try to use either one of the class i am having following error:
Cannot implicitly convert type 'RemoteFilesWatchService' to
'IWatchService'. An explicit conversion exists (are you missing a
cast?)
How to fix that to able to use in CollectionService either one mentioned class or another.
This is the full code:
public interface IWatch
{
void Watch();
}
public interface IWatchService<TDataEntity> where TDataEntity : IEntity
{
INotificationFactory NotificationFactory { get; }
ObservableCollection<TDataEntity> MatchingEntries { get; set; }
}
public interface IDatabaseWatchService<TDataEntity> : IWatchService<TDataEntity> where TDataEntity : IDatabaseEntity
{
IDatabaseRepository<IDbManager> DatabaseRepository { get; }
}
public interface IRemoteFilesWatchService<TDataEntity> : IWatchService<TDataEntity> where TDataEntity : IFileEntity
{
List<string> ExistingRemoteFiles { get; set; }
List<RemoteLocation> RemoteLocations { get; set; }
IWinScpOperations RemoteManager { get; set; }
IRemoteFilesRepository<IDbManager, TDataEntity> RemoteFilesRepository { get; }
}
public class RemoteFilesWatchService : IRemoteFilesWatchService<IFileEntity>, IWatch
{
public INotificationFactory NotificationFactory { get; }
public ObservableCollection<IFileEntity> MatchingEntries { get; set; }
public List<string> ExistingRemoteFiles { get; set; }
public List<RemoteLocation> RemoteLocations { get; set; }
public IWinScpOperations RemoteManager { get; set; }
public IRemoteFilesRepository<IDbManager, IFileEntity> RemoteFilesRepository { get; }
public RemoteFilesWatchService(IWinScpOperations remoteOperator,
IRemoteFilesRepository<IDbManager, IFileEntity> remoteFilesRepository,
INotificationFactory notificationFactory)
{
RemoteManager = remoteOperator;
RemoteFilesRepository = remoteFilesRepository; //csv, xml or other repo could be injected
NotificationFactory = notificationFactory;
}
public void Watch()
{
}
}
public class DatabaseWatchService : IDatabaseWatchService<DatabaseQuery>, IWatch
{
public INotificationFactory NotificationFactory { get; }
public ObservableCollection<DatabaseQuery> MatchingEntries { get; set; }
public IDatabaseRepository<IDbManager> DatabaseRepository { get; }
public DatabaseWatchService(IDatabaseRepository<IDbManager> databaseRepository,
INotificationFactory notificationFactory)
{
DatabaseRepository = databaseRepository;
NotificationFactory = notificationFactory;
}
public void Watch()
{
}
}
public class CollectionService
{
private IWatchService<IEntity> _watchService;
public CollectionService(IWatchService<IEntity> watchService)
{
_watchService = watchService;
}
}
class Run
{
void DoIt()
{
IWatchService<IEntity> fileWatcherServiceCsv = new RemoteFilesWatchService(new WinScpOperations(),
new RemoteCsvFilesRepository(new DbManager(ConnectionDbType.MySql)),
new NotificationFactory());
var coll1 = new CollectionService(fileWatcherServiceCsv);
}
}
public interface IEntity
{
}
public interface IFileEntity : IEntity
{
int Id { get; set; }
string Name { get; set; }
bool IsActive { get; set; }
bool RemoveFromSource { get; set; }
string DestinationFolder { get; set; }
RemoteLocation RemoteLocation { get; set; }
}
public interface IDatabaseEntity : IEntity
{
}
public class CsvFile : IFileEntity
{
public int ColumnHeader { get; set; }
public int ColumnsCount { get; set; }
public string Separator { get; set; }
public int ValuesRowStartposition { get; set; }
public int ColumnRowPosition { get; set; }
public int Id { get; set; }
public string Name { get; set; }
public bool IsActive { get; set; }
public bool RemoveFromSource { get; set; }
public string DestinationFolder { get; set; }
public RemoteLocation RemoteLocation { get; set; }
}
public class XmlFile : IFileEntity
{
public int Id { get; set; }
public string Name { get; set; }
public bool IsActive { get; set; }
public bool RemoveFromSource { get; set; }
public string DestinationFolder { get; set; }
public RemoteLocation RemoteLocation { get; set; }
public string SubNode { get; set; }
public string MainNode { get; set; }
}
Rather than having IWatchService expose a concrete type, I'd suggest instead having it require reimplementation of those interfaces from ObservableCollection that you actually want the consumers to use (or move those onto another interface and have that be what MatchingEntries returns).
Here I've guessed that the consumers want the events that the observable collection raises and to be able to enumerate the collection and that's all, which means we can a) implement those interfaces and b) make the interface covariant:
public interface IWatchService<out TDataEntity> :
INotifyCollectionChanged,
INotifyPropertyChanged,
IEnumerable<TDataEntity>
where TDataEntity : IEntity
{
INotificationFactory NotificationFactory { get; }
}
Now, if the implementations choose to use an ObservableCollection and just use simple wrappers to implement those interfaces or choose to satisfy the interface in some other way has been move back into an implementation decision.
I am trying to write a basic abstract class where any class that extends it will have a List of some type.
The context is I call a web service, and I receive "pages" of orders, and each order has "pages" of order lines, etc.
abstract class Pagination
{
public int _offset { get; set; }
public int _total { get; set; }
public string previous { get; set; }
public string next { get; set; }
// Can I add something here that represents a list of items
// that is overridden in child classes somehow?
// public abstract List<Something?> items { get; set; }
// The purpose is for this generic "getItemCount" function or something similar
/*
public int getItemCount()
{
return items != null ? items.Count() : 0;
}
*/
}
class OrderHeader : Pagination
{
public int orderId { get; set; }
public List<OrderLine> items { get; set; }
}
class OrderLine : Pagination
{
public string sku { get; set; }
public int qty { get; set; }
public List<OrderLineDetails> items { get; set; }
}
class OrderLineDetails
{
public string serialNum { get; set; }
}
You can do that with generics
public abstract class Pagination<T>
{
public abstract List<T> Items { get; set; }
}
public class OrderHeader : Pagination<OrderLine>
{
public override List<OrderLine> Items { get; set; }
}
public class OrderLine : Pagination<OrderLineDetails>
{
public override List<OrderLineDetails> Items { get; set; }
}
You can use generics, e.g.:
abstract class Pagination<T>
{
// Other properties
public List<T> items { get; set; }
}
class OrderHeader : Pagination<OrderLine>
{
// Other properties
}
class OrderLine : Pagination<OrderLineDetails>
{
// Other properties
}
class OrderLineDetails
{
// Other properties
}
As addition to answers containing overriding I'll try to show slightly different approach which may broaden horizons. If you'll change your abstract class implementation you don't even need to override your Collection unless you need explicit implementation for get; or set; because you're specifying generic by inheritance itself
abstract class Pagination<T>
{
public virtual List<T> Items { get; set; }
}
class Tester : Pagination<string>
{
public void Test()
{
foreach (string item in this.Items)
{
// you have declared List<string> from Pagination<T>
}
}
}
Also this one may be useful for you: Generic Type in constructor
By that approach you would ended up with one base class which will provide you your generic List
abstract class Pagination2<T>
{
public string Property1 { get; set; }
public List<T> Items { get; set; }
public static Pagination2<T> GetInstance<T>()
{
Pagination2<T> instance = new Pagination2<T>()
{
Items = new List<T>()
};
return instance;
}
}
abstract class Pagination<T>
{
public int _offset { get; set; }
public int _total { get; set; }
public string previous { get; set; }
public string next { get; set; }
public List<T> items { get; set; }
public int getItemCount()
{
return items != null ? items.Count() : 0;
}
}
class OrderHeader : Pagination<OrderLine>
{
public int orderId { get; set; }
}
class OrderLine : Pagination<OrderLineDetails>
{
public string sku { get; set; }
public int qty { get; set; }
}
I am creating a product website which have products and product categories, I have created the following classes:
public abstract class Product
{
public int ProductId { get; set; }
public string ProductName { get; set; }
public string ProductCode { get; set; }
public int ProductCatagoryId { get; set; }
}
public class DryFruits : Product
{
public decimal WeightInGrams { get; set; }
public decimal RatePerGram { get; set; }
}
public class DryFruitsPacks : Product
{
public string PackName { get; set; }
public decimal PackWeight { get; set; }
public decimal PackPrice { get; set; }
}
I want a method AddProduct(), which must be present in every class derived from product and adds that product to the database.
public class Product : IAddProduct
{
public int ProductId { get; set; }
public string ProductName { get; set; }
public string ProductCode { get; set; }
public int ProductCatagoryId { get; set; }
public virtual void Add(Product p)
{
//Save to db
};
}
public class DryFruits : Product
{
public decimal WeightInGrams { get; set; }
public decimal RatePerGram { get; set; }
public override void Add(Product p)
{
//Save to db
}
}
public interface IAddProduct
{
void Add(Product product)
}
Public class SomeClass
{
Product product = new DryFruits()
{
ProductName = "Nut";
WeightInGrams = 0.01;
}
private IAddProduct _saveIt;
_saveIt.Add(product)
}
Public class SomeOtherClass
{
Product product = new Product()
{
ProductName = "Orange";
}
private IAddProduct _saveIt;
_saveIt.Add(product)
}
I always consider abstract classes to be a poor man's version of an interface. Even with the code above it fits the purpose of the SO's requirements.
You should add an abstract class to you base Product class. and override it in your derived classes.
public abstract class Product
{
public int ProductId { get; set; }
public string ProductName { get; set; }
public string ProductCode { get; set; }
public int ProductCatagoryId { get; set; }
public abstract void Save();
}
public class DryFruits : Product
{
public decimal WeightInGrams { get; set; }
public decimal RatePerGram { get; set; }
public override void Save()
{
//save the product
}
}
Derived classes. When you create a derived class like DryFruits or DryFruitsPacks , you must provide an override method for all abstract methods in the abstract class. The AddProduct() method in both derived classes satisfies this requirement.
Override
Int field. An abstract class can have an instance field in it. The derived classes can access this field through the base syntax..
Int
Cannot instantiate abstract class. The important part of an abstract class is that you can never use it separately from a derived class.
public abstract class Product
{
public int ProductId { get; set; }
public string ProductName { get; set; }
public string ProductCode { get; set; }
public int ProductCatagoryId { get; set; }
public abstract void AddProduct(params object[] arguments);
}
Abstract methods
I have a set of POCO classes which implement IConnectable and IEntity.
In one of the classes, Connection, I want two properties that are defined as objects that implement IConnectable.
public interface IConnectable
{
string Name { get; set; }
string Url { get; set; }
}
And my connection class
public partial class Connection : IEntity
{
public int Id { get; set; }
public T<IConnectable> From { get; set; }
public T<IConnectable> To { get; set; }
public ConnectionType Type { get; set; }
public double Affinity { get; set; }
public DateTimeOffset CreatedOn { get; set; }
}
I know I can't use generic objects are properties -- so is there any other way to do this?
It's most likely appropriate to just not have generics at all :
public partial class Connection : IEntity
{
public int Id { get; set; }
public IConnectable From { get; set; }
public IConnectable To { get; set; }
public ConnectionType Type { get; set; }
public double Affinity { get; set; }
public DateTimeOffset CreatedOn { get; set; }
}
If it's important that instances of Connection return types of something more derived then you'll need to make the whole class generic:
public partial class Connection<T> : IEntity
where T : IConnectable
{
public int Id { get; set; }
public T From { get; set; }
public T To { get; set; }
public ConnectionType Type { get; set; }
public double Affinity { get; set; }
public DateTimeOffset CreatedOn { get; set; }
}
If you need to be able to have two different IConnectable types for the two properties, then you need to generic parameters:
public partial class Connection<TFrom, TTo> : IEntity
where TFrom : IConnectable
where TTo : IConnectable
{
public int Id { get; set; }
public TFrom From { get; set; }
public TTo To { get; set; }
public ConnectionType Type { get; set; }
public double Affinity { get; set; }
public DateTimeOffset CreatedOn { get; set; }
}