[DataContract]
public class OrderSyncData : ISync
{
public OrderSyncData(Order o)
{
this.CurrentOrderStatus = o.DriverStatus;
this.StatusDescription = o.StatusDescription;
SyncTimestamp = o.SyncTimestamp; ????
}
[DataMember]
public string CurrentOrderStatus { get; set; }
[DataMember]
public string StatusDescription { get; set; }
[DataMember]// I don't think I need these any more
public bool IsCanceled { get; set; }
[DataMember]
public bool IsResolved { get; set; }
[DataMember]
public bool IsPendingResponse { get; set; }
DateTime ISync.SyncTimestamp { get; set; }
}
How to set the value of ISync.SyncTimestamp? I tried casting the "this." but it doesn't work
This should work:
((ISync)this).SyncTimestamp = o.SyncTimestamp;
Note the extra braces around (ISync)this.
You just need to cast this:
((ISync) this).SyncTimestamp = o.SyncTimestamp;
Or you could do it in two statements:
ISync sync = this;
sync.SyncTimestamp = o.SyncTimestamp;
Basically, the explicit interface implementation means that the property is only available when you're viewing this in the context of simply ISync, not the implementation class.
This is because you've implemented SyncTimestamp explicitly. Explicit implementations cannot be accessed from a class instance. Why? Because explicit implementation allows you to implement multiple interfaces with the same member name.
class Foo: IBar, IFoo
{
bool IBar.FooBar {get;set;}
bool IFoo.FooBar {get;set;}
}
Then writing this.FooBar refers to which implementation? So either you cast this to the desired interface explicitly, like other answers suggest, or you don't implement the SyncTimestamp explicitly, but do it implicitly: public DateTime SyncTimestamp { get; set; }.
Then this.SyncTimestamp will work.
Related
I have a few interfaces that are
public interface ISaleOrderManager
{
Task<IOrderDto> CreateAsync(ICreateOrderDto request);
}
public interface ICreateOrderDto
{
long? ContactId { get; set; }
DateTime OrderDate { get; set; }
double TotalAmount { get; set; }
}
public interface IOrderDto:ICreateOrderDto,IEntityDto
{ }
public interface IEntityDto
{
long Id {get;set;}
bool isDeleted {get; set;}
}
also, I have some DTOs as well that are
public class CreateSaleOrderDto: ICreateOrderDto
{
public long? ContactId { get; set; }
public DateTime OrderDate { get; set; }
public double TotalAmount { get; set; }
}
public class SaleOrderDto : IOrderDto
{
public long Id {get;set;}
public bool isDeleted {get; set;}
public long? ContactId { get; set; }
public DateTime OrderDate { get; set; }
public double TotalAmount { get; set; }
}
And I implement ISaleOrderManager on a class that is
public class SaleOrderManager: ISaleOrderManager
{
public SaleOrderManager(IRepository<SaleOrder, long> entityRepository)
{
}
public async Task<SaleOrderDto> CreateAsync(CreateSaleOrderDto request)
{
var entity = ObjectMapper<SaleOrder>(request);
entity.Id = await _entityRepository.InsertAndGetIdAsync(entity);
return ObjectMapper.Map<SaleOrderDto>(entity);
}
}
So as my code depicts that I have implemented ICreateOrderDto through CreateSaleOrderDto and IOrderDto through SaleOrderDto but I'm still getting an error of "Interface Member is not implemented."
Why do I receive this error and how can I overcome it?
You didn't implement the Task<IOrderDto> CreateAsync(ICreateOrderDto request) method in the SaleOrderManager class. You made the CreateAsync method return a Task<SaleOrderDto> instead of a Task<IOrderDto>. Also you used a parameter of type CreateSaleOrderDto instead of ICreateOrderDto.
This is the declaration of the method
Task<IOrderDto> CreateAsync(ICreateOrderDto request);
and this is the attempt for the implementation
public async Task<SaleOrderDto> CreateAsync(CreateSaleOrderDto request)
{
var entity = ObjectMapper<SaleOrder>(request);
entity.Id = await _entityRepository.InsertAndGetIdAsync(entity);
return ObjectMapper.Map<SaleOrderDto>(entity);
}
I perfectly know that SaleOrderDto implements IOrderDto and that CreateSaleOrderDto implements ICreateOrderDto, but this does not qualify as an implementation of the method in the interface.
In order to understand the problem, let's consider the possibility that some other class, that may be different from CreateSaleOrderDto may also implement ICreateOrderDto. If I declare a variable to be an ISaleOrderManager and I instantiate this other class, let's call it MyCustomCreateSaleOrderDto and pass it to CreateAsync, then I justifiably expect your method to work, but it will not work, because your method mistakenly assumed the following:
It assumed that each and every iCreateOrderDto is a CreateSaleOrderDto
It assumed that each and every IOrderDto is a SaleOrderDto
You should aim to write your code in an as abstract manner as possible, so, you should aim to implement your method in a way that it expects a parameter specified as an interface and its return type should also be corresponding to the one specified by the interface, even though they are actual objects at runtime.
I want to create an interface which can handle multiple other object of one interface.
I tried using the interface in the interface and using an object in the new class.
public interface IObject
{
double Value { get; set; }
}
public class FirstObject: IObject
{
double Value { get; set; }
}
public class SecondObject: IObject
{
string Titel { get; set; }
double Value { get; set; }
}
public interface ICollection
{
IObject[] Values { get; set; }
}
public class Collection: ICollection
{
SecondObject[] Values { get; set; }
}
Now I get the error, that my Collection doesn't implement the IObject[] Values member.
I thought when I use an object (SecondObject) which is implementing from the interface IObject the Collection should handle this.
What am I doing wrong and how can I solve this?
You might be off better here using generics:
public interface ICollection<T> where T : IObject
{
T[] Values { get; set; }
}
public class Collection : ICollection<SecondObject>
{
public SecondObject[] Values { get; set; }
}
The reason that it doesn't work now, is that the signature should match exactly. That means the Values should be an array of IObject, which it isn't. Using generics you can solve this, while keeping the type constraint.
A second, but inadvisable solution would be using an explicit interface implementation:
public SecondObject[] Values { get; set; }
IObject[] ICollection.Values
{
get
{
return this.Values;
}
set
{
this.Values = value?.Cast<SecondObject>().ToArray();
}
}
There is the following class:
public class A
{
[Required]
public string property { get; set; }
}
and it's used by another class like:
public class B
{
public A prop { get; set; }
public A prop2 { get; set; }
}
in my scenario, B.prop.property should be required while B.prop2.property should not be [Required].
Is there a way to override prop2.property attribute to be not required? and it also should affect the record recorded in the Database?
if not what is the most recommended practice to deal with such issue?
No. There is no way to achieve what you're talking about. You can do so via inheritance. For example:
public class C : A
{
public new string property { get; set; }
}
Then:
public class B
{
public A prop { get; set; }
public C prop2 { get; set; }
}
In other words, the property must literally be a type where that property is not required. You can't just disable an attribute on a class instance at a whim.
i have two data classes which hold only data members(no functions). One is CallTask the other is SmsTask. These two classes have some common properties like ID, Tel. I put these common properties in a seperate interface class and i use this interface class in my project whenever appropriate.
Now i added a WCFService to my project to share data between clients and server. Consider the following class design:
public interface IGsmTask : IComparable
{
string TaskID { get; set; }
string SessionID { get; set; }
string Tel { get; set; }
}
class CallTask : IGsmTask
{
#region IGsmTask Members
public string TaskID { get; set; }
public string SessionID { get; set; }
public string Tel { get; set; }
#endregion
}
class SmsTask : IGsmTask
{
#region IGsmTask Members
public string TaskID { get; set; }
public string SessionID { get; set; }
public string Tel { get; set; }
#endregion
public string SmsText { get; set; }
}
in this design, i want to host CallTask, SmsTask, and IGsmTask to the clients to use these in service methots like the following;
[OperationContract]
public void AddTask(IGsmTask task)
{
}
i tried to mark [DataContract] on IGsmTask but it gives me complition error. Isnt there any methot that i can use interfaces as DataContracts? Or how should i use KnownAttributes types in this synerio?
Thanks.
As far as I know using interfaces as datacontracts is not possible. You may use a base class and add knowntype attributes on the otherhand.
Fer: Everything is Possible with the right design.
If the issue is:
a class is a data contract
&&
1 or more of its properties must be an interface...
public interface ICustomInterface
{
int Property1 {get;set}
}
[DataContract]
public class MyClass
{
[DataMember(Name="_myInterface")]
public ICustomInterface MyInterface {get;set;}
}
The issue is that when the de-serialization occurs --
There is no way to turn the data into a class that implements ICustomInterface.
The Solution is to create a concrete class that does Implement the interface, and cast the getter/setter of the public property (that is of type interface) into a private property of the concrete class.
public class CustomInterfaceImplementor: ICustomInterface
{
public int Property1 {get;set;}
}
[DataContract]
public class MyClass
{
[DataMember(Name="_myInterface")]
private CustomInterfaceImplementor _MyInterface;
public ICustomInterface MyInterface
{
get {return (_MyInterface as ICustomInterface);}
set {_MyInterface = (value as CustomInterfaceImplementor);}
}
}
I have the following interface declarations:
interface IOrder<T> where T: IOrderItem
{
IList<T> Items { get; set; }
}
interface IOrderItem
{
IOrder<IOrderItem> Parent { get; set; } // What do I put here?
}
I want the items in the list to have a reference to the header object, so it can use the ID and other fields from the header.
In my concrete classes, it complains that I don't implement "Parent" properly.
class StoreOrder : IOrder<StoreOrderItem>
{
public IList<StoreOrderItem> Items { get; set; }
}
class StoreOrderItem : IOrderItem
{
public StoreOrder Parent { get; set; } // This doesn't satisfy the interface
}
I tried setting up IOrderItem as IOrderItem<T> and passing in the Parent type, but that lead to circular reference since the Header class requries the Item class type... I got confused.
Any advice on how to implement this properly?
If you define your interfaces like so:
interface IOrder<T> where T : IOrderItem<T>
{
IList<T> Items { get; set; }
}
interface IOrderItem<T> where T : IOrderItem<T>
{
IOrder<T> Parent { get; set; }
}
You can then implement them like this to get the functionality that you expect:
class StoreOrder : IOrder<StoreOrderItem>
{
public IList<StoreOrderItem> Items { get; set; }
}
class StoreOrderItem: IOrderItem<StoreOrderItem>
{
public IOrder<StoreOrderItem> Parent { get; set; }
}
class StoreOrder : IOrder<StoreOrderItem>
{
public int Id { get; set; }
}
class StoreOrderItem : IOrderItem
{
public IOrder<IOrderItem> Parent { get; set; } // This doesn't satisfy the interface
}
You may not specialize - IOrder<IOrderItem> is more general than StoreOrder
Here's a solution for changing the interfaces:
interface IOrder<TOrder, TOrderItem>
where TOrderItem : IOrderItem<TOrder>
{
IList<TOrderItem> Items { get; set; }
}
interface IOrderItem<TOrder>
{
TOrder Parent { get; set; }
}
Making changes to StoreOrder and StoreOrderItem to support the interface changes AND adding a couple properties to each for a later test:
class StoreOrder: IOrder<StoreOrder, StoreOrderItem>
{
public DateTime Date { get; set; }
public IList<StoreOrderItem> Items { get; set; }
}
class StoreOrderItem : IOrderItem<StoreOrder>
{
public string ItemName { get; set; }
public decimal ItemPrice { get; set; }
public StoreOrder Parent { get; set; }
}
...and now creating StoreOrder and StoreOrderItem instances, and putting them through their paces:
void Main()
{
var so = new StoreOrder { Date = DateTime.Now };
var item = new StoreOrderItem {
Parent = so,
ItemName = "Hand soap",
ItemPrice = 2.50m };
so.Items = new [] { item };
Console.WriteLine(item.Parent.Date);
Console.WriteLine(so.Items.First().ItemName);
}
...when run, printed:
3/16/2012 10:43:55 AM
Hand soap
Another option is to scrap the above and take this solution and alter it by adding the Parent property with the desired type and using explicit interface implementation to avoid casting at the call-sites, making for a StoreOrderItem implementation something like this:
class StoreOrderItem : IOrderItem
{
public string ItemName { get; set; }
public decimal ItemPrice { get; set; }
public StoreOrder Parent { get; set; } // note: original implementation
IOrder<IOrderItem> IOrderItem.Parent { // explicit interface implementation
get { return (IOrder<IOrderItem>)this.Parent; }
set { this.Parent = (StoreOrder)value; }
}
}
My favorite of the above is the first proposal above with the two-generic parameters to IOrder and the unconstrained generic-parameter on IOrderItem. A previous version I had posted and have now edited had both interfaces each with the same two generic types each with the same constraints. I felt like this was going a bit overboard so I pared it back to the above implementation. Although there is a complete lack of constraints on TOrder type parameter to IOrderItem - attempts to fudge other types in its place (e.g., object) resulted in compile errors. Using TOrder instead of just calling it T provides a hint about the expected type in the absence of the type constraint. That will be my final edit - I feel it is the most succinct of my attempts; if you are curious I can provide the former implementation that had the double-generic-constrained-types on the interfaces, but this is at least my preferred this solution. cheers!
Declaration to satisfy the interfaces:
class StoreOrder : IOrder<StoreOrderItem>
{
// interface members
public IList<StoreOrderItem> Items { get; set; }
// own members
public int Id { get; set; }
}
class StoreOrderItem : IOrderItem
{
public IOrder<IOrderItem> Parent { get; set; }
}
To access custom members you will have to cast:
class StoreOrderItem : IOrderItem
{
void Test()
{
int id = ((StoreOrder)this.Parent).ID;
}
}