Explicit Interface Implementation and Multiple Interfaces - c#

In some locations of my program I need access to the concrete implementation of an object (Test) and in other locations I only need a read-only interface (ITest). This is to prevent an user from assuming that all properties are set and modifiable
For example if the user calls TestFactory.Search the returned collection will prevent them from modifying the property A and using CollectionB (it is not set inside the function). I would like to be able to use object initializers and keep the properties names the same. I have the following solution:
public interface IReadOnly
{
int Id{ get; }
string Name{ get; }
}
public class ClassA : IReadOnly
{
int Id{ get; internal set; }
string Name{ get; set; }
}
public interface ITest
{
int Id{ get; }
IReadOnly A { get; }
}
public class Test : ITest
{
private ClassA classA = new ClassA();
int Id{ get; internal set; }
IReadOnly ITest.A{ get{ return classA; } }
public ClassA A
{
get
{
return classA;
}
set
{
classA = value;
}
}
public IEnumerable<string> CollectionB {get;set;}
}
public static class TestFactory
{
IEnumerable<ITest> Search(){ /**/ }
Test Read(){ /**/ };
}
Is there a better way to solve this problem and is the abusing the concept of explicit interface implementation?

I would have your Test class implement both interfaces, IReadOnly and ITest. When you want to restrict setter access, cast to IReadOnly, otherwise, use ITest or the concrete Test.

Maybe create an abstract class instead and then subclass the full access and read only behavior?

Related

Passing Generic Input object to a method C#

I have a method ABC() which gets called from two different places in my application. And from both places I have different objects of class which is implemented a common interface "IDestination".
My two classes and Interface are looking like this:
public class ClassA: IDestination
{
public string Var1 { get; set; }
public string Var2 { get; set; }
public string Var3 { get; set; }
}
public class ClassB: IDestination
{
public string Var1 { get; set; }
public string Var2 { get; set; }
public string Var3 { get; set; }
public string Var4 { get; set; }
public string Var5 { get; set; }
}
public interface IDestination
{
string Var1 { get; set; }
string Var2 { get; set; }
}
As of now Method ABC() accepts the object of classA, I want it can also accept the object of classB. For this I have made my method defination generic like below:
public string ABC<T>(T obj)
{
}
But, the problem is inside the ABC method I want to access the properties of classes (classA and classB both).
public string ABC<T>(T obj)
{
//Some code
obj.var2; //of classA
obj.var4; //of classB
//Some code
}
And I can't allowed to do any changes in the interface.
How can I achieve this? I do not want to create another method for handling different class objects. Any idea?
First of all, interfaces aren't inherited but implemented.
In the other hand, generic parameters can be constrained:
public string ABC<T>(T obj) where T : IDestination
OP said:
And I can't allowed to do any changes in the interface.
BTW, with your requirement and just with generic type constraints you won't be able to accept both classA and classB because C# doesn't support multi-inheritance. If you want to access classB members, you'll need to expand your IDestination interface to define all properties you want to access in a classB typed as IDestination:
public interface IDestination
{
string Var1 { get; set; }
string Var2 { get; set; }
string Var3 { get; set; }
string Var4 { get; set; }
string Var5 { get; set; }
}
Or you can define a second interface with the rest of properties:
public interface IDestination2
{
string Var3 { get; set; }
string Var4 { get; set; }
string Var5 { get; set; }
}
...and you'll implement it on classB:
public class ClassB: IDestination, IDestination2
Anyway, the problem here is that you can't constraint a generic parameter to accept two different inheritances of some given classes. That is, for example, if you constraint T to be both IDestination and IDestination2, you won't be able to give ClassA as argument, because it doesn't implement IDestination2.
OP said:
I do not want to create another method for handling different class objects.
Actually this could be also solved without generics but with method overloading and it's not an evil approach even when you don't want to go this route:
public void ABC(IDestination destination) {}
public void ABC(IDestination2 destination) {}
// or directly...
public void ABC(ClassA destination) {}
public void ABC(ClassB destination) {}
Otherwise, you'll need to implement this as follows:
public string ABC<T>(T obj) where T : IDestination
{
ClassA a = obj as ClassA;
ClassB b = obj as ClassB;
// Now if you want to access Var1, Var2 you can access them
// using "obj" reference, because T is IDestination
string var1 = obj.Var1;
string var2 = obj.Var2;
if(a != null)
{
// Here access all ClassA members...
}
if(b != null)
{
// Here access all ClassB members...
}
}
For me, above approach is a design flaw. If I use generic types and interfaces is because I want to work with objects that equal the typing of the generic type parameter.
If I start to perform downcasts to particular implementations of the interface, it's like defeating the purpose of using IDestination and it seems like your method could be just accepting object because your method will access ClassA and ClassB members instead of IDestination ones:
public string ABC(object obj)
{
ClassA a = obj as ClassA;
ClassB b = obj as ClassB;
// Now if you want to access Var1, Var2 you can access them
// using "obj" reference, because T is IDestination
string var1 = obj.Var1;
string var2 = obj.Var2;
if(a != null)
{
// Here access all ClassA members...
}
if(b != null)
{
// Here access all ClassB members...
}
return "";
}
TL;DR
In summary, you should use interfaces to type your objects and generic constraints to guarantee a minimum typing on your references in order to avoid casts. Otherwise, generic typing isn't your solution.
You should definitly re-think your design. When your method accepts instances of the interface it should work for all types, not only a set. Imagine you create a third type that also implements the interface. You would have to re-implement the whole method to support this. Therefor all the properties should be defined on the interface instead of the class-level and then can be accessed within the method.
However if you really have to use your current approach you can simply cast it to the appropriate type:
ClassA a = obj as ClassA;
if (a != null) a.Var2 = ...
// this will fail if a user provides an instance of ClassC which also implements the interface
else ((ClassB)obj).Var4 = ...
For this to work you will also need a constraint on your gegernic parameter:
public string ABC<T>(T obj) where T : IDestination
I think that a better design is the following:
public string ABC<T>(T obj) where T : IDestination
{
}
I say so, because since you want a generic method for object that implements the IDestination interface, it would be better as a design, If you have declared it as constraint. For this, please have a look here.
Then in order you access the field that you want in the ABC, the interface should have all this properties. So If we assume that you want both classes A and B have the same three properties Var1, Var2 and Var3 and you want to access them in the ABC, then you have t redecclare your interface as below:
public interface IDestination
{
string Var1 { get; set; }
string Var2 { get; set; }
string Var3 { get; set; }
}
You can use the reflection class to handle that problem, you can get the properties of parameter in the runtime and you can use also.
Type type = typeof(obj);
PropertyInfo[] propertyList = type.GetProperties();
Well, to achieve what you want you need to implement the ABC method to accept a type of IDestination:
public string ABC<T>(T obj) where T : IDestination
But for that to work, you then have to change your interface to have all the methods you want to access:
public interface IDestination
{
string Var1 { get; set; }
string Var2 { get; set; }
string Var3 { get; set; }
string Var4 { get; set; }
string Var5 { get; set; }
}
Then you have to change your classes to implement all the members of the interface which means you might end up with something like this:
public class ClassA : IDestination
{
public string Var1 { get; set; }
public string Var2 { get; set; }
public string Var3 { get; set; }
public string Var4
{
get
{
throw new NotImplementedException();
}
set
{
throw new NotImplementedException();
}
}
public string Var5
{
get
{
throw new NotImplementedException();
}
set
{
throw new NotImplementedException();
}
}
}
public class ClassB : IDestination
{
public string Var1 { get; set; }
public string Var2 { get; set; }
public string Var3 { get; set; }
public string Var4 { get; set; }
public string Var5 { get; set; }
}
But it doesn't make a lot of sense to have the extra methods implemented in ClassA if they just throw an exception. So you might as well just fully implement them. But then ClassA and ClassB are identical. So you have to ask yourself what is unique enough about each class to justify a separate concrete implementation of IDestination? Answering that question will guide you on what to do.
EDIT:
Since you can't change the interface, are you forced to use the interface in method ABC? Can you create an abstract class that both ClassA and ClassB inherit from?
public abstract class ClassAB : IDestination //might not need the interface
{
public virtual string Var1 { get; set; }
public virtual string Var2 { get; set; }
public virtual string Var3 { get; set; }
public virtual string Var4 { get; set; }
public virtual string Var5 { get; set; }
}
public class ClassA : ClassAB
{
//override any of the virtual methods needed
}
public class ClassB : ClassAB
{
//override any of the virtual methods needed
}
Then change ABC method:
public string ABC(ClassAB classAB)
{
//all the methods are available on classAB
}
Both ClassA and ClassB would still be of type IDestination because the abstract parent class implements it. The only question is if you can change method ABC to expect a type of ClassAB instead of IDestination?
I think it will be hard to handle type-specific properties in generic method as it doesn't know what is the specifics of such properties. I would recommend delegating this logic to a method, that the classes will implement via interface.
As you mentioned in your comment, you can't change the interface IDestination and you don't want to break the compatibility as this solution is already used in many places. So the proposition is not to change ClassA and ClassB logic that is already working, but add new interface implementation, that will cover this type-conditional logic you wanted to implement in your ABC method.
I would add another interface that holds method doing all the type-conditional logic and simply call it in the middle of your ABC class. In order to keep the constraints your generic type would need to implement both IDestination and IDestinationLogic interface. Of course the ABC method may need slight modifications but it's hard to say how precisely should it look like, given that we totally don't know anything about what it should do.
An example implementation could look like that:
public class GenericMethodClass
{
public string ABC<T>(T obj) where T : IDestination, IDestinationLogic
{
var result = string.Empty;
//some code happens here
var typeConditionalLogicResult = obj.DoSomething();
// do more stuff with according to the result of type-specific calculations
return result;
}
}
public class ClassA: IDestination, IDestinationLogic
{
public string Var1 { get; set; }
public string Var2 { get; set; }
public string Var3 { get; set; }
public string DoSomething()
{
return Var2;
}
}
public class ClassB: IDestination, IDestinationLogic
{
public string Var1 { get; set; }
public string Var2 { get; set; }
public string Var3 { get; set; }
public string Var4 { get; set; }
public string Var5 { get; set; }
public string DoSomething()
{
return Var4;
}
}
public interface IDestination
{
string Var1 { get; set; }
string Var2 { get; set; }
}
public interface IDestinationLogic
{
string DoSomething();
}
The approach I suggested with interfaces is very similar to the template method design pattern, which initially included abstract classes. You can read about it here: http://www.dofactory.com/net/template-method-design-pattern maybe it will put more light on your case
you can use Reflection for getting these value like this:
public static string ABC<T>(T obj)
{
string s=string.Empty;
//Some code
if(obj is ClassA)
s = obj.GetType().GetProperty("Var2").GetValue(obj, null).ToString(); //of classA
if (obj is ClassB)
s = obj.GetType().GetProperty("Var4").GetValue(obj,null).ToString(); //of classB
//Some code
return s;
}

How to force implementation of an abstract classes members in the inheriting class?

I have the following two classes:
abstract class LogItem {
public String payload { get; set; }
public String serverId { get; set; }
public DateTime timeRecieved { get; set; }
}
class MyLogItem : LogItem
{
//No I want this to have to have the members from the abstract class above, as if it where an interface?
}
So in other words I am wanting a type if interface that can have definitions or variables which all classes that implement it have to have, but they could add more if they required ?
The above example builds, even if i dono add the members from the abstract class.
edit
Forget what I've said before. These are attributes, not methods. For them to be accessible on derived classes, you make them protected or public. The difference is that public members are visible to the world, while protected ones are visible to the class and subclasses.
Any class derived from your LogItem may have other variables.
abstract class LogItem {
public String payload { get; set; }
public String serverId { get; set; }
public DateTime timeRecieved { get; set; }
}
class MyLogItem : LogItem
{
//No I want this to have to have the members from the abstract class above, as if it where an interface?
private void TestMethod(){
String test = payload;
}
}
check out this post for more information
Your MyLogItem class can reference any of the above members directly. They are accessible
You may declare an interface with those
public interface MyInterface {
public String payload { get; set; }
public String serverId { get; set; }
public DateTime timeRecieved { get; set; }
}
and your class
public class MyLogItem : MyInterface
{
String _payload;
public String payload { get{ return _payload; } set {_payload=value;} }
...
}
The abstract keyword can also be applied to methods, as described here.

How to hide implementation

Lets say I have a class library, where any classes that are internal have access to the following interface:
interface myInterface
{
string myProperty { get; set; } // notice setter.
}
But if somebody adds this class library to their project they get the following interface:
public interface myInterface
{
string myProperty { get; }
}
What is the most efficient and accepted way of doing this? Have one interface implement the other?
Make your public interface have just the getter:
public interface myInterface
{
string myProperty { get; }
}
And then derive another internal-only interface from it that has a setter:
internal interface myInternalInterface : myInterface
{
new string myProperty { get; set; }
}
You can them implement the internal interface:
class myImplementation : myInternalInterface
{
public string myProperty{get; set;}
}
If you need to call the setter, you can cast your instance to the internal inteface and call it on that. This approach is a bit of a design smell though, so use it sparingly.
You can have the internal interface extend the public interface, like so:
public interface MyInternalInterface: MyPublicInterface
{
string MyProperty { set; }
}
public interface MyPublicInterface
{
string MyProperty { get; }
}
internal class A: MyInternalInterface
{
public string MyProperty { get; set; }
}
public class Foo
{
private A _a = new A();
internal MyInternalInterface GetInternalA() { return _a; }
public MyPublicInterface GetA() { return _a; }
}
This way you don't need any casts or anything.
I thought that #adrianbanks' answer might be an improvement on mine, however I don't think it really is (despite being nifty) - because you have no guarantee that a public interface instance being passed to you also implements the internal one - which is also true of this solution. There's also the thing that it only works if the implementing type is internal - which is no good if you want to supply public types as standard interface implementations or as bases for a hierarchy.
This is what I use. Given:
interface myInterface
{
string myProperty { get; set; }
}
public interface myPublicInterface
{
string myProperty { get; }
}
First you can't make myPublicInterface inherit myInterface because the compiler will moan about inconsistent accessibility. So you can explicitly implement the internal one, using a property backer, and then implement the public one implicitly:
public class MyClass : myInterface, myPublicInterface
{
private string _myProperty;
string myInterface.myProperty
{
get { return _myProperty; }
set { _myProperty = value; }
}
public string myProperty
{
get { return _myProperty; }
}
}
Note - in some cases, the getter might not be suitable for a private backer, but might be some logic that calculates values from other properties. In which case - to keep it DRY - you can put the logic in the public getter, and leech that for the explicit getter:
string myInterface.myProperty
{
get { return MyProperty; }
set { /*whatever logic you need to set the value*/ }
}
public string myProperty
{
get { /*whatever complex logic is used to get the value*/ }
}
You can do it the other way around, but you have to do a horrible-looking inline cast to the internal interface:
string myInterface.myProperty
{
get { /*whatever complex logic is used to get the value*/ }
set { /*whatever logic you need to set the value*/ }
}
public string myProperty
{
get { return ((myInterface)this).myProperty; }
}
Which you should try to steer clear of wherever possible.

how to mark an interface as DataContract in WCF

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);}
}
}

C#: interface inheritance getters/setters

I have a set of interfaces which are used in close conjunction with particular mutable object.
Many users of the object only need the ability to read values from the object, and then only a few properties. To avoid namespace pollution (easier intellisense) and to get across the usage intent, I'd like to have a small base interface which only exposes a few "key" properties in a read-only fashion.
However, almost all implementations will support the full interface, which includes modifiability.
Unfortunately, I ran into a roadblock expressing that concept in C#:
interface IBasicProps {
public int Priority { get; }
public string Name {get;}
//... whatever
}
interface IBasicPropsWriteable:IBasicProps {
public int Priority { set; } //warning CS0108: [...] hides inherited member [...]
public string Name { set; }
//... whatever
}
I certainly wasn't intending to hide any members, so that aint good!
Of course, I can solve this using methods just fine, but what's the right choice? I'd like to keep the "core" interface as small as possible even if splitting the interfaces serves no purpose other than communicating intent. With split interfaces, it's just really obvious which methods aren't going to do any updating, and it makes writing code a bit clearer (not to mention also allows nice-n-simple static singleton stubs that suffice for quite a few simple cases).
I'd like to avoid any abstract classes and the like; they make reimplementation or quick single-purpose shims all that more complex and hard-to-grok.
So, ideas?
Method hiding in an interface isn't nearly as grungy; I'd go with something like:
interface IBasicProps {
int Priority { get; }
string Name {get;}
//... whatever
}
interface IBasicPropsWriteable:IBasicProps {
new int Priority { get; set; }
new string Name { get; set; }
//... whatever
}
class Foo : IBasicPropsWriteable {
public int Priority {get;set;}
public string Name {get;set;}
/* optional
int IBasicProps.Priority {get {return Priority;}}
string IBasicProps.Name {get {return Name;}}
*/
}
If your goal is to make it clearer when reading vs. writing is allowed, then I would use separate getter and setter methods rather than properties.
interface IBasicProps {
int GetPriority();
string GetName();
//... whatever
}
interface IBasicPropsWriteable:IBasicProps {
void SetPriority(int priority);
void SetName(string name);
//... whatever
}
One way could be to simply skip the inheritance of the interfaces. Make one read-only interface and one write-only, and implement as necessary:
interface IBasicPropsReadable {
int Priority { get; }
string Name { get; }
}
interface IBasicPropsWriteable {
int Priority { set; }
string Name { set; }
}
class SomeClassReadWrite : IBasicPropsReadable, IBasicPropsWriteable {
int Priority { get; set; }
string Name { get; set; }
}
class SomeClassReadOnly : IBasicPropsReadable {
int Priority { get; }
string Name { get; }
}
You could leave the interfaces unrelated and simply have your class implement both interfaces. After all the interfaces are simply defining the contract and the contracts don't need to be related. It seems like it just an optimization for you when coding to have the writeable one derive from the other, so you only have to specify one interface.
public interface IBasicProps
{
int Priority { get; }
string Name {get;}
//... whatever
}
public interface IBasicPropsWriteable
{
int Priority { get; set; }
string Name { get; set; }
//... whatever
}
public class Foo : IBasicProps, IBasicPropsWriteable
{
public int Priority { get; set; }
public string Name { get; set; }
// whatever
}
If you really needed the optimization, you could create another interface that derives from both and have your classes implement that.
public interface IBasicPropsAll : IBasicProps, IBasicPropsWriteable { }
public class Foo : IBasicPropsAll
{
public int Priority { get; set; }
public string Name { get; set; }
// whatever
}

Categories