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>
Related
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?
I have a rather simple problem, but I can't find a proper solution anywhere. I would like to specify an abstract object CustomValues as property in my abstract parent class. However, the class inheriting from it should be able to use a more specific type as an object for this property CustomValues. At first I thought I would solve the problem by an interface, but unfortunately that didn't work out either. How do you do something like that, that it works?
public abstract class MyAbstract {
public abstract object CustomValues { get; set; }
}
public class MyImplementation : MyAbstract {
public override MySpecificClass CustomValues { get; set; }
}
This will throw me three errors:
Missing implementation for getter
Missing implementation for setter
Type missmatch between type object and MySpecificClass
The solution suggested in the comments would look something like this. (I'm assuming CustomValues should be a collection of something.)
public class MyClass<T>
{
public ICollection<T> CustomValues { get; set; }
}
Or to ensure CustomValues itself cannot be reassigned, but can be accessed and added to:
public class MyClass<T>
{
public ICollection<T> CustomValues { get; } = new List<T>();
}
I think your original thought that use an interface (+ generic) was at the correct direction. In general you might want to add type constraints as well.
public interface ICustomValues {
....
}
public class MySpecificClass : ICustomValues {
....
}
public abstract class MyAbstract<T> where T : ICustomValues {
public abstract T CustomValues {
get;
set;
}
}
public class MyImplementation: MyAbstract<MySpecificClass> {
public override MySpecificClass CustomValues { get; set; }
}
Thanks to you all guys. I found the solution by using a generic properly:
public abstract class MyAbstract<T> {
public abstract T CustomValues { get; set; }
}
public class MyImplementation : MyAbstract<MySpecificClass> {
public override MySpecificClass CustomValues { get; set; }
}
I have two similar classes, so I made a parent class, and 2 classes which derive from it. The thing is that they are both trees of only their own type. So for now I have a parent class which holds a reference list of public IList<ParentTreeClass> Children { get; set; }. How can I change the ParentTreeClass to force it to be derived from ParentTreeClass not including it.
To give a bit more specific example, lets call the classes ParentTreeClass, ImportTree and ExportTree.
public class ParentTreeClass {
public ParentTreeClass Parent { get; set; }
public IList<ParentTreeClass> Children { get; set; }
// Other stuff.
}
public class ImportTree : ParentTreeClass {
// Some overrides.
}
public class ExportTree : ParentTreeClass {
// Some other overrides.
}
As said, once I have a ExportTree object, its children and parent should also be ExportTree and no other object.
I have thought about Generics like so:
public class ParentTreeClass<T> {
public T Parent { get; set; }
public IList<T> Children { get; set; }
// Other stuff.
}
But this is not restrictive enought, since I want T to be a child of ParentTreeClass. I tried adding where T : ParentTreeClass. This does not work, cause it tells me to use where T : ParentTreeClass<T>, then I run into issues understanding the second T.
Can I force a tree to be instances of the same type which derives from ParentTreeClass?
It's fairly simple to do.
public class ParentTreeClass<T> where T : ParentTreeClass<T> {
public T Parent { get; set; }
public IList<T> Children { get; set; }
// Other stuff.
}
public class ImportTree : ParentTreeClass<ImportTree> {
// Some overrides.
}
public class ExportTree : ParentTreeClass<ExportTree> {
// Some other overrides.
}
This has the drawback that you can go on to define a class like this:
public class ImportTree2 : ParentTreeClass<ExportTree> {
// Some overrides.
}
But, so long as you're careful with your definitions this works fine.
You could do like this:
public class ParentTreeClass<T> where T: ITree
{
public T Parent { get; set; }
public IList<T> Children { get; set; }
// Other stuff.
}
public interface ITree
{
IList<ITree> Children { get; set; }
ITree Parent { get; set; }
}
public class ImportTree : ParentTreeClass<ITree>, ITree
{
// Some overrides.
}
public class ExportTree : ParentTreeClass<ITree>, ITree
{
// Some other overrides.
}
Restriction is not subclass of parent but it restricts T by ITree implementations only
I have one class with a generic type, like this:
public class Test<T> {
/*
Some Properties and Fields
*/
}
Now I need a public Property SubTest{T} in class Test{T} with datatype Test{T}
public class Test<T> {
/*
Some Properties and Fields
*/
public Test<T> SubTest { get; set; }
}
T and U are not the same datatype and SubTest can be null.
Is that possible in C#?
Update
Or like This?
public class Test {
/*
Some Properties and Fields
*/
public Type ElementType { get; private set; }
public Test SubTest { get; set; }
public Test(Type elementType) {
ElementType = elementType;
}
}
U it not defined so it cannot be used like the. You need to create type parameter in the class, or use a specific type, for example string:
public class Test<T, U> {
/*
Some Properties and Fields
*/
public Test<T,U> SubTest { get; set; }
}
Your question is a bit inconsistent:
Now I need a public Property SubTest{T} in class Test{T} with datatype
Test{T}
But your example is different, and now U has been added.
public class Test<T>
{
public Test<U> SubTest { get; set; }
}
So to answer your question as-is, replace U with T:
public class Test<T>
{
public Test<T> SubTest { get; set; }
}
I think what you are trying to do is to create a generic "test" object, and then have multiple implementations (with different types). I would use interfaces instead, but its the same concept with classes.
public interface ITest
{
// general test stuff
}
// Type-specific stuff
public interface ITesty<T> : ITest
{
public ITest SubTest { get; set; } // a sub-test of any type
}
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