How to implement Interface which defines element of another Interface - c#

Interface A
{
string x {get;set;}
IEnumarable<InterfaceB> DetailList { get; set; }
}
Interface B
{
int z;
int y;
}
Class B :Interface B
{
implements z;
implements y;
}
Class A :Interface A
{
implements x;
IEnumarable<ClassB> DetailList {get;set;} // This line is giving trouble.
}
Is this code violating OO concept. I thought if I derive ClassB from InterfaceB then I can use ClassB in my ClassA instead of InterfaceB. VS is not liking this, Its asking me to use InterfaceB instead of ClassB in ClassA.
Is there any other way to go about doing this.
I am willing to consider alternate designing options, I have some domain objects whose properties are defined by Interface A and each domain object would have corresponding object defined by interface B
e.g
concert(A) concertlocations(B)
comedyshow(A) comedyshowlocations(B)
Feel free to ask more questions if you think I am not being clear enough.
Thanks in Advance

You can this:
public interface InterfaceA<T> where T : InterfaceB
{
string x {get;set;}
IEnumerable<T> DetailList { get; set; }
}
public interface InterfaceB
{
int z { get; }
int y { get; }
}
public class ClassB : InterfaceB
{
public int z { get; private set; }
public int y { get; private set; }
}
public class ClassA : InterfaceA<ClassB>
{
public int z { get; private set; }
public string x { get; set; }
public IEnumerable<ClassB> DetailList {get;set;}
}
but I'm not sure this is desirable for you?
see here for more info: c# interface implemention - why does this not build?

Interface A just says that the IEnumarable<InterfaceB> DetailList { get; set; } has to be present in any class, that is implementing it, with exactly InterfaceB being the generic type for IEnumerable, and not one of it's implementaions.
Class B is less general than Interface B, therefore it is completely logical that it does not allow you to use it in such manner.

Related

c# cannot cast from 'IInterface<IOtherInterface>' to 'IInterface - Convert class without generic to interface with generic

I Have the interface IJob which is an parameter in many of my functions. But this interface is actually generic (IJob<T>). I want to avoid passing the generic Parameter around to all functions. So i did something like the following:
public interface ISomeType
{
string X { get; set; }
}
public interface IJob<T>
where T : ISomeType
{
string SomeProp { get; set; }
T GenericProp { get; set; }
}
public interface IJob : IJob<ISomeType> { }
public class Job<T> : IJob<T>
where T : ISomeType
{
public string SomeProp { get; set; }
public T GenericProp { get; set; }
}
public class Job : Job<ISomeType> { }
public class SomeOtherType : ISomeType
{
public string X { get; set; }
public string Y { get; set; }
}
So my functions now look like this:
public void DoSomething(IJob job){}
//instead of:
public void DoSomething<T>(IJob<T> job)
where T:ISomeType {}
I Want to do that beacause those functions never touch GenericProp - they only need to know that T is ISomeType
Everything works fine, but i came to a point where the following will not work:
I want to store all Jobs in a IDictionary<string,IJob> jobs and i don´t know the type of GenericProp before runtime. So i need to cast a Job<T> to IJob in order to add it to the Dictionary, but this throws an casting Error.
IJob job = (IJob)new Job<SomeOtherType>();
In general i don´t feel like my solution is a best-practice. But how do I work with polymorphic classes instead?

inheriting interfaces and COM-interop best practices?

I have a question that is not a direct coding problem, so I am not sure this is the place to ask. If not please advise on where better to ask.
I have a .Net assembly exposed to COM. It uses a base class and several derived classes, all exposed via interfaces.
Base class:
public abstract class BaseFoo : IBaseFoo
{
public abstract int X { get; }
public abstract int Y { get; }
}
with interface:
public interface IBaseFoo
{
int X { get; }
int Y { get; }
}
Derived classes are COM-visible and add additional functionality.
[ComVisible(true)]
[Guid("123-456-789")]
[ClassInterface(ClassInterfaceType.None)]
[ComDefaultInterface(typeof(IFooA))]
public class FooA : BaseFoo, IFooA
{
public override int X { get; }
public override int Y { get; }
public string Z { get; set; }
}
The interface is exposed to COM:
[ComVisible(true)]
[Guid("321-654-987")]
public interface IFooA : IBaseFoo
{
string Z { get; set; }
}
At this point, people who have worked with COM will notice a problem. IFooA will be exposed to COM, but it will not expose anything from IBaseFoo, because inherited interfaces do not make it to COM.
To overcome that, I did this:
[ComVisible(true)]
[Guid("321-654-987")]
public interface IFooA : IBaseFoo
{
new int X { get; }
new int Y { get; }
public string Z { get; set; }
}
Which finally brings me to my question: I do not like that new in there. It feels wrong overriding the inherited interface. Would it be better to create a separate interface IComFooA, have FooA inherit from it, and expose that interface to COM, the clean up IFooA so as to be just .Net? In essence: would you advise the setup sketched above or the one sketched below, and why?
[ComVisible(true)]
[Guid("123-456-789")]
[ClassInterface(ClassInterfaceType.None)]
[ComDefaultInterface(typeof(IComFooA))]
public class FooA : BaseFoo, IFooA, IComFooA
{
public override int X { get; }
public override int Y { get; }
public string Z { get; set; }
}
with IComFooA being:
[ComVisible(true)]
[Guid("321-654-987")]
public interface IComFooA
{
int X { get; }
int Y { get; }
public string Z { get; set; }
}
And IFooA being just:
public interface IFooA : IBaseFoo
{
public string Z { get; set; }
}

If I have two interfaces, can one class inherit both?

I have a class with 2 interfaces, and I have some superclasses with subclasses, I would like the superclasses to inherit both interfaces. if I just reference the class the interfaces its in, will it work? ie SuperClass : Myinterfaces
here is the class with the interfaces
public class Myinterfaces
{
public interface IBakeable
{
int OvenTemp { get; }
}
public interface IAccounting
{
int Cost { get; }
}
public enum Colors
{
red = 1,
blue,
yellow
}
}
and heres an example of the superclass
public class CeramicsSuperClass : Myinterfaces
{
public string ItemName { get; set; }
public int Cost { get; set; }
public int OvenTemp { get; set; }
}
public class Vases : CeramicsSuperClass
{
private int _BaseDiam;
public Vases(int diam)
{
_BaseDiam = diam;
}
}
You are doing in a wrong way to implement multi-interfaces for a class, try this instead:
public class CeramicsSuperClass : IBakeable, IAccounting {
public string ItemName { get; set; }
public int Cost { get; set; }
public int OvenTemp { get; set; }
}
A class can inherit from only another class but it can implement as many interfaces as possible. When a class inherits from another class and implement some interface, the base class should be listed first, then the interfaces go after like this:
//class A inherits from class B and implements 2 interfaces IC and ID
public class A : B, IC, ID {
//...
}
Simple answer:
You can inherit mulitple interfaces, not multiple classes.
public interface InterfaceA
{
string PropertyA {get;}
}
public interface InterfaceB
{
string PropertyB {get;}
}
public abstract class BaseClassForOthers : InterfaceA, InterfaceB
{
private string PropertyA {get; private set;}
private string PropertyA {get; private set;}
public BaseClassForOthers (string a, string b)
{
PropertyA = a;
PropertyB = b;
}
}
public class SubClass : BaseClassForOthers
{
public SubClass (string a, string b)
: base(a, b)
{
}
}
may be looking here will get you in the general direction (msdn link about interface usage):
http://msdn.microsoft.com/en-us/library/vstudio/ms173156.aspx

Will change from abstract class to sealed class break simple client use

I'm changing a class from public abstract AwesomeClass, to public sealed AwesomeClass. I've also added a new property. All existing members are unchanged. I know that this is a breaking change. Clients that have implemented AwesomeClass or relied on it being abstract via reflection will be broken.
My question is, will clients that have only used members of instances of AwesomeClass that I've provided, be broken (and if yes how)? None of the clients will have a dependency on any of my types that implemented AwesomeClass as they were all internal. I think not, but...
Here is the class before and after:
public abstract class AwesomeClass
{
public abstract Guid SuperGuid { get; set; }
public abstract int SuperInt { get; set; }
}
public sealed class AwesomeClass
{
public Guid SuperGuid { get; set; }
public int SuperInt { get; set; }
public int OtherSuperInt { get; set; }
}
You mean that when you have this:
public abstract class Foo
{
public string Bar;
}
void UpdateFooBar(Foo foo)
{
foo.Bar = "Updated";
}
And you change abstract class Foo to sealed class Foo, will UpdateFooBar(Foo foo) continue to work?
What kept you from trying? But yes, it will.

Specifying multiple interfaces for a parameter

I have an object that implements two interfaces... The interfaces are:
public interface IObject
{
string Name { get; }
string Class { get; }
IEnumerable<IObjectProperty> Properties { get; }
}
public interface ITreeNode<T>
{
T Parent { get; }
IEnumerable<T> Children { get; }
}
such that
public class ObjectNode : IObject, ITreeNode<IObject>
{
public string Class { get; private set; }
public string Name { get; private set; }
public IEnumerable<IObjectProperty> Properties { get; set; }
public IEnumerable<IObject> Children { get; private set; }
public IObject Parent { get; private set; }
}
Now i have a function which needs one of its parameters to implement both of these interfaces. How would i go about specifying that in C#?
An example would be
public TypedObject(ITreeNode<IObject> baseObject, IEnumerable<IType> types, ITreeNode<IObject>, IObject parent)
{
//Construct here
}
Or is the problem that my design is wrong and i should be implementing both those interfaces on one interface somehow
public void Foo<T>(T myParam)
where T : IObject, ITreeNode<IObject>
{
// whatever
}
In C#, interfaces can themselves inherit from one or more other interfaces. So one solution would be to define an interface, say IObjectTreeNode<T> that derives from both IObject and ITreeNode<T>.
It's probably easiest to define an interface that implements both IObject and ITreeNode.
public interface IObjectNode<T> : IObject, ITreeNode<T>
{
}
Another option, in case you don't expect the above interface would be used often, is to make the method/function in question generic.
public void Foo<T>(T objectNode) where T : IObject, ITreeNode<IObject>
public void MethodName<TParam1, TParam2>(TParam1 param1, TParam2 param2)
where TParam1 : IObject
where TParam2 : ITreeNode<IObject>

Categories

Resources