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; }
}
Related
I have a class from an external library which I need to extend into antoher class. Also the extensions should remain reusable, as I need them also to be implemented in other places.
As neither mixins nor multiple inheritance are supported in C#, whats the common way to solve this?
namespace ExtLib
{
public class Properties
{
public virtual int fieldN { get; set; }
}
}
namespace MyLib
{
public class Extensions
{
public virtual int fieldM { get; set; }
}
}
namespace MyProject
{
public class MyModel
{
// needs to have all fields from ExtLib.Properties AND MyLib.Extensions
}
public class MyOtherModel
{
// needs to have all fields from MyLib.Extensions,
// MyLib.Extensions should be reusable
}
}
I know a solution could be an interface IExtensions, however this leads to alot of duplication as the number of the fields of Extensions and Properties are quite high (and in the development phase they change alot).
Are there any best practices?
How about you just aggregate instances of these classes into MyModel?
public class MyModel
{
private Properties _properties;
private Extensions _ extensions;
public MyModel(Properties properties, Extensions extensions)
{
_properties = properties;
_extensions = extensions;
}
public Properties Prop
{
get { return _properties; }
}
public Extensions Ext
{
get { return _extensions; }
}
}
Alternatively, you can of course get rid of manual backing fields and use auto-implemented properties with a public getter and private setter.
All changes to Properties and Extensions will be automatically reflected in MyModel. Aggregation is a common way of using design patterns in an object oriented manner as opposed to class manner, which regularly uses multiple inheritance.
As for polymorphism issues, you can create a derived class, override any behavior you want and pass an instance of that class into the constructor.
Create an abstract class that is derived from ExtLib, then derive MyProject from your abstract class
namespace ExtLib
{
public class Properties
{
public virtual int fieldN1 { get; set; }
public virtual int fieldN2 { get; set; }
public virtual int fieldN3 { get; set; }
public virtual int fieldN4 { get; set; }
public virtual int fieldN5 { get; set; }
}
}
namespace MyLib
{
abstract class Extensions : Properties
{
public virtual int fieldM1 { get; set; }
public virtual int fieldM2 { get; set; }
public virtual int fieldM3 { get; set; }
public virtual int fieldM4 { get; set; }
public virtual int fieldM5 { get; set; }
}
}
namespace MyProject
{
public class MyModel : Extensions
{
// contains all fields from ExtLib.Properties AND MyLib.Extensions
}
}
I want to inherit some properties that are the same in 2 classes using interface or abstract class; I don't want to declare variable in child classes.
Is it possible to do this?
Parent Class:
interface IError
{
DateTime GETDATE { get; set; }
string ERROR_NUMBER { get; set; }
string ERROR_SEVERITY { get; set; }
string ERROR_STATE { get; set; }
string ERROR_PROCEDURE { get; set; }
string ERROR_LINE { get; set; }
string ERROR_MESSAGE { get; set; }
}
Child :
public class Business
{
public Business()
{
this.Id = -1;
this.Message = "";
}
public int Id { get; set; }
public string Message { get; set; }
}
Another child:
public class DbTools
{
//Another Class
}
I need parent properties in this two classes, but if change code like below, I should use another variable that I don't want to:
public class Business : IError
{
private DateTime m_GetDATE;//I don't want to declare another variable
public DateTime GETDATE
{
get { return m_GetDATE; }
set { GETDATE = m_GetDATE; }
}
}
Sounds like you want an abstract base class:
public abstract class ErrorBase : IError
{
public DateTime GETDATE { get; set; }
//...ditto all the other IError properties
}
Then you can just inherit that:
public class Business : ErrorBase
{
// all the ErrorBase properties are inherited
}
You could also make the base class properties virtual just in case you need to override them in the derived classes at any point.
The other thing you might consider is composing rather than inheriting. It doesn't seem all that natural that Business and DbTools should be inheriting from the same base class, so instead have a (non-abstract) ErrorBase class that implements IError and have Business and DbTools have an Error property:
public class ErrorBase : IError
{
public DateTime GETDATE { get; set; }
//...ditto all the other IError properties
}
public interface IHaveError
{
ErrorBase Error { get; set; }
}
public class Business : IHaveError
{
public ErrorBase { get; set; }
}
As a bonus, you could make IHaveError actually be IHaveErrors and have a List<ErrorBase> property allowing your objects to hold more than one error, which might be useful sometimes.
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
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.
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>