Suppose to have an interface like this:
interface MyInterface
{
public string AProperty { get; set;}
public void AMethod ()
}
This interface is used inside another interface:
interface AnotherInterface
{
public MyInterface member1 { get; set; }
public int YetAnotherProperty {get; set;}
}
Now suppose to have two classes, one that implements each of the interfaces.
class MyInterfaceImpl : MyInterface
{
private string aproperty
public string AProperty
{
//... get and set inside
}
public void AMethod ()
{
//... do something
}
}
And at last:
class AnotherInterfaceImpl : AnotherInterface
{
private MyInterfaceImpl _member1;
public MyIntefaceImpl member1
{
//... get and set inside
}
...Other implementation
}
Why does the compiler complain that AnotherInterfaceImpl does not implement MyInterface?
I understand it is a very basic question... but I need to serialize to xml AnotherInterfaceImpl and I cannot do that if member1 is of type MyInterface.
Your class AnotherInterfaceImpl is not actually implementing all members of AnotherInterface. The public property AnotherInterfaceImpl.member1 must have type MyInterface, not MyInterfaceImpl.
Note that this restriction only applies to the public property. The private field AnotherInterfaceImpl._member1 can still be of type MyInterfaceImpl, because MyInterfaceImpl implements MyInterface.
Why the compiler complains that AnotherInterfaceImpl does not implement MyInterface?
Because it doesn't implement it. It has a member that implements it.
That is like saying "my customer object has an orders (list) property; how come my customer isn't a list?"
If you had either:
interface AnotherInterface : MyInterface
or
class AnotherInterfaceImpl : AnotherInterface, MyInterface
then it would be true to say that AnotherInterfaceImpl implemented MyInterface.
you need to "explicitly" type your members as the interface defines them.
class AnotherInterfaceImpl : AnotherInterface
{
private MyInterfaceImpl _member1;
public MyInteface member1
{
get{ return _member1;}
set{ _member1 = value;}
}
...Other implementation
}
Related
I have an interface which has a property like this:
public interface IMyInterface
{
IGenericThing MyProperty { get; set; }
}
I implement that interface in a specific class that uses a generic type, but in that class, I want to use a specific implementation of IGenericThing, like this:
public abstract class MySpecificClass<T> : IMyInterface
where T : IGenericThing
{
IGenericThing IMyInterface.MyProperty
{
get { return myProperty; }
set
{
if (value is T)
{
MyProperty = (T)value;
}
}
}
protected T myProperty;
public T MyProperty
{
get { return myProperty; }
set
{
myProperty = value;
//...other setter stuff
}
}
}
This all works, which is awesome. It lets me access MyProperty when I have a reference to an object through IMyInterface, and access more specific information about MyProperty when I know it's an instance of MySpecificClass.
What I don't really understand is what this is called or what the compiler is doing to let this happen. I tried searching for this, but since I don't know what it's called, couldn't find anything.
Can anybody please explain what is going on here so that I can understand this better?
That's called explicit interface implementation
if a class implements two interfaces that contain a member with the same signature, then implementing that member on the class will cause both interfaces to use that member as their implementation.
It's not exactly your case but here you have a classic usage for it
interface IControl
{
void Paint();
}
interface ISurface
{
void Paint();
}
public class SampleClass : IControl, ISurface
{
void IControl.Paint()
{
System.Console.WriteLine("IControl.Paint");
}
void ISurface.Paint()
{
System.Console.WriteLine("ISurface.Paint");
}
}
I need to make some of my classes inherit from Interface with generic field
like that
public Interface ICommon<Ttype>
{
Ttype Filed{get;set;}
}
public Class class1:Icommon<int>
{
int Filed{get;set;}
}
public Class class2:Icommon<double>
{
double Filed{get;set;}
}
I created a generic class with constraints that uses classes class1 and class2 to make some operations like that:
public Class GenericClass<Ttype,Tcommon> where Ttype:ICommon<Tcommon>
{
//forexample
public Ttype someOperation(Ttype x)
{
var a=x.Field;
//.............
}
}
every time I use the GenericClass I have to know the type of Field of the class I used say class1 or class2 to be able to pass it to match the generic constraint
Is there a way to write GenericClass like that:
public Class GenericClass<Ttype,Tcommon> where Ttype:**ICommon**
{
//forexample
public Ttype someOperation(Ttype x)
{
var a=x.Field;
//.............
}
}
by writting ICommon without <TCommon> ??
Update:
or how to edit ICommon interface to be like that
public Interface ICommon
{
Ttype Filed{get;set;}
}
I hope I understood what you intended to do:
public interface ICommon<T>
{
T Field { get; set; }
}
public class GenericClass<T>
{
public ICommon<T> SomeOperation(ICommon<T> x)
{
// do your stuff
}
}
Short answer is: no.
You need to tell the compiler type of generic argument.
In fact, GenericClass<int> and GenericClass<string> are two different classes in CLR.
Is there a way to assign T through instantiation as in the following "hypothetical" example:
MyObject DummyObject = new MyObject();
DummyObject.MyNestedObject = new MySecondObject<string>()
public class MyObject //**Normally is specified as MyObject<T>**
{
public MySecondObject<T> MyNestedObject { get; set; }
}
I want to define T on instantiation of MySecondObject. I dont want to define it in MyObject.
No, you have to declare T in your class. Otherwise T won't exist in that context.
public class MyObject<T>
Another way would be to create an interface, implement it in your MySecondObject generic class.Then make the property type to interface instead of MySecondObject<T>
interface IMyInterface
{
}
class MySecondObject<T> : IMyInterface
{
}
public class MyObject
{
public IMyInterface MyNestedObject { get; set; }
}
I have the following class:
public class DataInterop <T> where T : ITableAdapter
{
private ITableAdapter tableAdapter;
public DataInterop(T tableAdapter)
{
this.tableAdapter = tableAdapter;
}
}
In the ITableAdapter-Interface are Methods defined like Read(), Write(...), Update(...), Delete(...), ...
Now I want the Class DataInterop to have all Methods from the ITableAdapter interface.
Is it possible for a generic-class to inherit from an interface?
You just need to add : ITableAdaper after the DataInterop<T>
public class DataInterop<T>: ITableAdapter where T: ITableAdapter
{
private ITableAdapter tableAdapter;
public DataInterop(T tableAdapter)
{
this.tableAdapter = tableAdapter;
}
}
(It looks like you're implementing an Adapter Pattern or a Decorator Pattern.)
Yes it is possible, it's especially useful when you handle instances of the class without knowing the concrete type at runtime.
The syntax would be:
public class DataInterop <T> : ITableAdapter where T : ITableAdapter
Ofcourse you can. Sample layout -
public interface IBar
{
string Name { get; set; }
}
public class Foo<T> : IBar
{
public string Name { get; set; }
}
I have a property A in all subclasses of base class Base.
How can I generate an abstract property definition of property A into base class Base?
I know ReSharper's refactoring Pull Members Up, but that moves the property to base class.
I need an abstract property in base class and a overriding properties in all sub classes. Is there a refactoring in Visual Studio or in ReSharper that can do it automatically for me?
There is a checkbox "Make abstract" for that in ReSharper Pull Members Up dialog :
I'm not sure Resharper can move up and create an abstraction as you want automatically, but you can atleast define it manually like this
In abstract class:
public abstract double A
{
get;
}
In Sub class:
public override double A
{
get
{
return 3.141;
}
}
It might be a clearner design to define a new Interface (or use an existing one) and define the property in the interface. That way, your existing subclasses won't have to use override.
public interface IInterface {
string MyProperty { get; }
}
public class Class : IInterface {
public string MyProperty { get; set; }
}
public abstract class AbstractClass {
public abstract string Value { get; }
}
public class ConcreteClass : AbstractClass {
private string m_Value;
public override string Value {
get { return m_Value; }
}
public void SetValue(string value) {
m_Value = value;
}
}
I hope this will be helpful to you.