I want to create an object that implements an interface and t hen return a reference to it. I've seen how to test whether the object implements an interface but I'm not sure how to do it in the first place.
The interface is as follows:
public interface IInformation
{
string name { get; set; }
string description { get; }
string age { get; set; }
}
And this is where I am trying to create the object, in a new class:
public IInformation NewInformation(string description)
{
}
Any help would be appreciated!
To implement a interface you need to create a class say 'myClass' in my example and use the ':' symbol followed by the interface name. then right click the interface and press the button 'implement interface' this will auto generate all of the methods of your interface but you need to make sure that you change the default implementation from
throw new NotImplementedException();
to whatever logic you wish to use.
public interface IInformation
{
string name { get; set; }
string description { get; }
string age { get; set; }
}
public class myClass : IInformation
{
public string age
{
get
{
throw new NotImplementedException();
}
set
{
throw new NotImplementedException();
}
}
public string description
{
get
{
throw new NotImplementedException();
}
}
public string name
{
get
{
throw new NotImplementedException();
}
set
{
throw new NotImplementedException();
}
}
}
Then to use the class you will need to do something like this:
public IInformation NewInformation(string description)
{
myClass myInstance = new myClass();
myInstance.description = description;
return myInstance;
}
Related
I have the following design goal in a class hierarchy:
There is a BaseClass defining some properties, which would usually be read/write:
public class Media
{
public virtual object Content { get; set; }
public virtual double recordingLength { get; set; }
}
The intention is to have some subclasses where this property now is readonly:
public class CompactDisk : Media
{
public override object Content
{
get { return this.getContent(); }
set {
// THERE SHOULDN'T BE A SETTER
}
}
public override double recordingLength
{
get { return 74; }
set {
// NO SETTER EITHER HERE!
}
}
}
I'm lost here, because I don't know how should I implement my design intent.
One possible approach is using interfaces.
You can split your base concept into two interfaces:
public interface IWritableMedia
{
object Content { set; }
double recordingLength { set; }
}
public interface IReadOnlyMedia
{
object Content { get; }
double recordingLength { get; }
}
And then something like CompactDisk should only implement IReadOnlyMedia:
public class CompactDisk : IReadOnlyMedia
{
public object Content { get { return ......; } }
public double recordingLength { get { return .......; } }
}
If you want to implement a CD-RW (rewritable), you should implement both interfaces:
public class RewritableCompactDisk : IReadOnlyMedia, IWritableMedia
{
public object Content { get; set; }
public double recordingLength { get; set; }
}
This way you can type your variables as IReadOnlyMedia or IWritableMedia:
IReadOnlyMedia media = new CompactDisk();
IWritableMedia media2 = new RewritableCompactDisk();
Now the issue is IWritableMedia doesn't provide getters and you don't want to declare another variable of type IReadOnlyMedia. The solution is designing a third interface called IReadWriteMedia and RewritableCompactDisk should implement it:
public interface IReadWriteMedia : IReadOnlyMedia, IWritableMedia
{
}
public class RewritableCompactDisk : IReadWriteMedia
{
public object Content { get; set; }
public double recordingLength { get; set; }
}
Since IReadWriteMedia implements IReadOnlyMedia and IWritableMedia, now you'll be able to type variables with IReadWriteMedia and access both getters and setters:
IReadWriteMedia media3 = new RewritableCompactDisk();
object content = media3.Content;
media3.Content = "hello world";
You can't, or really shouldn't, have a design where the sub types "hide" functionality of the base type. You can:
In your setters throw a NotSupportedException, or similar. This is how the Stream class behaves when you try to set the length of a stream that cannot be set.
Change your design. I don't see a way to get properties working the way you want (without resorting to "hiding", which IMHO isn't a good solution), but perhaps something like this:
public interface IMedia
{
object Content { get; }
double RecordingLength { get; }
}
public interface IWritableMedia : IMedia
{
void SetContent(object content);
void SetRecordingLength(double length);
}
Your CompactDisk would implement the just the IMedia interface, whereas a HardDrive class may choose to implement the IWritableMedia interface.
I have an interface IProduct and two partial classes SearchedProductInternal and SearchedProductExternal.
These two classes are extending classes coming from 3rd party webservice searches but both return slightly different result types.
I want to use the interface for both so they type returned is the same. I know how to inherit but what do I do to return the "Name" as both the interface and SearchedProductInternal have the same object name?
My Interface is similar to as follows:
public interface IProduct
{
string Name { get; }
string ID { get; }
string DescriptionShort { get; }
string DescriptionLong { get; }
}
My Object SearchedProductInternal has the following properties:
string Name;
int ObjectIdField;
string DescriptionShortField;
string DescriptionLongField;
So my this is where I am inheriting
public partial class SearchedProductInternal : IProduct
{
public string ID
{
get { return ObjectIdField.ToString(); }
}
public string Name
{
//What do I do here?
}
public string DescriptionShort{get { return shortDescriptionField; }
}
public string DescriptionLong {get { return longDescriptionField; }
}
}
I want to the return the name that has been originality assigned in the SearchedProductInternal class but I don't know how to do that because if I just put
return Name
I get a stackoverflow error as it appears to be just keeping calling its self?
I think what you should do here is to explicitly implement the interface, so that you will have both your Name property as defined in the class and the IProduct.Name property from your interface.
You can explicitly implement the interface, like so:
public partial class SearchedProductInternal : IProduct
{
string IProduct.ID
{
get { return ObjectIdField.ToString(); }
}
string IProduct.Name
{
get { return "Interface name"; }
}
string IProduct.DescriptionShort
{
get { return shortDescriptionField; }
}
string IProduct.DescriptionLong
{
get { return longDescriptionField; }
}
// Name property for the class, not the interface
public string Name
{
get { return "Class name"; }
}
}
This way you can differentiate between calls to your interface properties and properties with the same name on your class.
When accessing both properties you can also decide which you want, in the following manner:
var test = new SearchedProductInternal();
Console.WriteLine(test.Name); // returns "Class name"
Console.WriteLine((test as IProduct).Name); // returns "Interface name"
If your SearchedProductInternal already defines the property Name and you're trying to return the value of same Name property, you don't have to do anything.
Don't create one more property named Name. Just get rid of the Name property you added. Everything should work because the class already implemented the contract defined by the interface IProduct.
If you want to return different value from the IProduct.Name property, you can use explicit interface implementation.
You must change the name of the variable in this case Name.
If that was an ambigous sentence then remember it's the same for the PC. Name cannot be two things. but Name and _Name can.
public class SearchedProductInternal : IProduct
{
string _name = "test";
public string Name
{
get
{
return _name;
}
}
}
public interface IProduct
{
string Name { get; }
}
I agree with the above answer. But a minor issue here, we cannot expose the interface member as public, as it causes compile error.
We can have both class level and interface level members. The interface member cannot be accessed by using class instance, which can be accessed only through interface instance.
public interface IProduct
{
string Name { get; }
string ID { get; }
string DescriptionShort { get; }
string DescriptionLong { get; }
}
public partial class SearchedProductInternal : IProduct
{
private string _clsName;
private string _interfaceName;
private string _objectID;
private string _shortDesc;
private string _longDesc;
public SearchedProductInternal(string _cName, string _iName)
{
_clsName = _cName;
_interfaceName = _iName;
}
public string Name
{
get { return _clsName; }
}
string IProduct.Name
{
get { return _interfaceName; }
}
string IProduct.ID
{
get { return _objectID; }
}
string IProduct.DescriptionShort
{
get { return _shortDesc; }
}
string IProduct.DescriptionLong
{
get { return _longDesc; }
}
}
class Program
{
static void Main(string[] args)
{
SearchedProductInternal clsSearchProduct = new SearchedProductInternal("clsName", "interfaceName");
Console.WriteLine(clsSearchProduct.Name);
IProduct interfaceProduct = (IProduct)clsSearchProduct;
Console.WriteLine(interfaceProduct.Name);
Console.ReadLine();
}
}
I am not sure if I just explained this in a way that was not understood but the way that I got this to work was by just using {get;set;}
public partial class SearchedProductInternal : IProduct
{
public string ID
{
get { return ObjectIdField.ToString(); }
}
public string Name {get;set;}
public string DescriptionShort{get { return shortDescriptionField; }
}
public string DescriptionLong {get { return longDescriptionField; }
}
}
I am having an issue with an explicit interface that I created and am getting the exception,
'x' does not contain a definition for 'y' and no extension method 'y' accepting a first argument of type 'x' could be found
I have a series of classes. The base class:
public interface IFactoryResponse
{
object instance { get; set; }
string instanceconfig { get; set; }
}
The class that explicitly implements it:
public class FactoryResponseImpl : IFactoryResponse
{
object IFactoryResponse.instance {
get { return ((IFactoryResponse)this).instance; }
set { ((IFactoryResponse)this).instance = value; }
}
string IFactoryResponse.instanceconfig {
get { return ((IFactoryResponse)this).instanceconfig; }
set { ((IFactoryResponse)this).instanceconfig = value; }
}
}
and in another class I get the above error. Visual studio can find the interface and class ok, but it can't resolve the instance property. What am I missing here. I am probably missing one of the more refined rules of explicit inheritance.
if (facconfig.useabstract) {
response.instance = Activator.CreateInstance(m_entassembly.GetType(entconfig.Classname, true, true));
response.instanceconfig = facconfig.config;
} else {
Assembly assem = Assembly.LoadFrom(facconfig.assemblyfile);
object Obj = Activator.CreateInstance(assem.GetType(facconfig.Classname, true, true));
response.instance = Obj;
response.instanceconfig = facconfig.config;
}
Your implementation is incorrect. It will cause StackOverflowException because property calls itself. You can easily implement the properties using autoproperties:
public class FactoryResponseImpl : IFactoryResponse
{
object IFactoryResponse.instance { get; set; }
string IFactoryResponse.instanceconfig { get; set; }
}
When interface member is implemented explicitly you have to look at variable as the interface, either by casting your class instance to that interface or assigning it into a variable types as that interface.
if (facconfig.useabstract) {
((IFactoryResponse)response).instance = Activator.CreateInstance(m_entassembly.GetType(entconfig.Classname, true, true));
((IFactoryResponse)response).instanceconfig = facconfig.config;
} else {
Assembly assem = Assembly.LoadFrom(facconfig.assemblyfile);
object Obj = Activator.CreateInstance(assem.GetType(facconfig.Classname, true, true));
((IFactoryResponse)response).instance = Obj;
((IFactoryResponse)response).instanceconfig = facconfig.config;
}
Why do you need the interface to be implemented explicitly? You shouldn't do that unless you have very good reason. With implicit implementation everything is much easier:
public class FactoryResponseImpl : IFactoryResponse
{
public object instance { get; set; }
public string instanceconfig { get; set; }
}
And your other code should work just fine.
Your explicit implementations are referencing themselves. You should be referencing a private field or the public implementation. E.g.:
public class FactoryResponseImpl : IFactoryResponse
{
DatabaseFactoryResponseInstance _instance;
public FactoryResponseImpl()
{
_instance = new DatabaseFactoryResponseInstance();
}
object IFactoryResponse.instance {
get { return (object)_instance; }
set {
if (value != null)
{
DatabaseFactoryResponseInstance dbInstance;
dbInstance = value as DatabaseFactoryResponseInstance;
if (dbInstance == null)
throw new InvalidOperationException();
_instance = dbInstance;
}
}
}
Is this what you where aiming for?
public interface IFactoryResponse
{
object instance { get; set; }
string instanceconfig { get; set; }
}
public class FactoryResponseImpl : IFactoryResponse
{
object IFactoryResponse.instance { get; set; }
string IFactoryResponse.instanceconfig { get; set; }
}
class Test
{
public void TestMethod()
{
IFactoryResponse response = new FactoryResponseImpl();
response.instance = null;
}
}
If one uses explicit interface implementations like IFactoryResponse.instance, then these methods are not publicly visible. Either you need to cast to IFactoryResponse to access them or define the methods as public: public object instance { ... }.
I wrote a nested class which is used as a bag for properties. This class is used as property which I named Properties. I want to extend number of properties by interfaces.
I wrote this example:
public interface IFirst {
int asd { get; set; }
}
public interface ISecond {
int zxc { get; set; }
}
public class MyClass {
public class PropertyClass : IFirst {
public int asd {
get {
throw new NotImplementedException();
}
set {
throw new NotImplementedException();
}
}
}
public PropertyClass Properties;
}
public class MyNextClass : MyClass {
public class PropertyClass : MyClass.PropertyClass, ISecond {
public int zxc {
get {
throw new NotImplementedException();
}
set {
throw new NotImplementedException();
}
}
}
public void test() {
Properties.zxc = 5; // Here is problem
}
}
But in this case I cant to read/write new property zxc.
I think because this still is reading a Properties type from parent class - MyClass.PropertyClass and not MyNextClass.PropertyClass.
I want to extending this without creating new property or hiding existing.
Do you have any suggestions?
You'll have to either ensure that the parent class implements both interfaces, or you'll have to create a new static member in the child class that is of the the nested child type. As you surmise, Properties is declared as being of the parent nested type, and declaring a new type in the child class of the same name that derives from the parent nested type doesn't change that.
Well, depending on what you’re trying to achieve approaches may vary. For instance, using abstract class might feet your needs. Like this:
public interface IFirst
{
int asd { get; set; }
}
public interface ISecond
{
int zxc { get; set; }
}
public abstract class MyAbstractClass<T> where T : class
{
public abstract T Properties {get; set;}
}
public class MyClass : MyAbstractClass<MyClass.PropertyClass>
{
public class PropertyClass : IFirst
{
public int asd
{
get { throw new NotImplementedException(); }
set { throw new NotImplementedException(); }
}
}
public override MyClass.PropertyClass Properties
{
get { throw new NotImplementedException(); }
set { throw new NotImplementedException(); }
}
}
public class MyNextClass : MyAbstractClass<MyNextClass.PropertyClass>
{
public class PropertyClass : MyClass.PropertyClass, ISecond
{
public int zxc
{
get { throw new NotImplementedException(); }
set { throw new NotImplementedException(); }
}
}
public override MyNextClass.PropertyClass Properties
{
get { throw new NotImplementedException(); }
set { throw new NotImplementedException(); }
}
public void test()
{
Properties.zxc = 5;
}
}
So, first I have my command property interface
public interface ICommandProperty<T, U>
{
Func<T> CreateCommand { get; set; }
Func<T, U> ParseResponse { get; set; }
}
The idea is that I can create a simple parser that takes a string and returns an IPAddress for example.
This interface is then used in another interface:
public interface IDeviceCommand
{
Func<ICommandProperty<object, object>> SetCommand
{
get;
set;
}
Func<ICommandProperty<object, object>> GetCommand
{
get;
set;
}
string Name { get; set; }
}
I may be going about this all wrong, but this is where I have the problem. Currently I have the generic interface declared with objects because I can't figure out a way to set them generically(IDeviceCommand can't be generic for various reasons).
My concrete implementation looks like this:
public class DeviceCommand:IDeviceCommand
{
public DeviceCommand(string name,Func<ICommandProperty<object,object>> Set,Func<ICommandProperty<object,object>> Get)
{
this.Name = name;
this.SetCommand = Set;
this.GetCommand = Get;
}
#region IDeviceCommand Members
public string Name
{
get;
set;
}
public object Value
{
get;
set;
}
public Func<ICommandProperty<object, object>> SetCommand
{
get;
set;
}
public Func<ICommandProperty<object, object>> GetCommand
{
get;
set;
}
#endregion
}
I could make DeviceCommand be a generic class, and use T,U on the SetCommand and GetCommand, but then it doesn't satisfy the IDeviceCommand interface because Func<ICommandProperty<T,U>> isn't Func<ICommandProperty<object,object>>
Is there a different approach that I should be using here. In essence I'm trying to create a method pointer that I can set when I instantiate DeviceCommand.
Your questions seems a little vague, but here's some ideas. The first is to consider using methods instead of properties so that they can be generic rather than the class. Not sure if that will work for you. You could also consider passing a "builder" object into your Device command rather than the func<>'s themselves. Lastly, this gets hairy with your client knowing what to ask for and ensuring it is working with an object that has the correct func<> available. In that case, maybe something like the IDeviceCommand.Create and .Parse methods could work for you.
Lastly, if you are always looking for something to take a string and return an IP, the generics may not be necessary. Even plain old delegates could be explored.
public interface ICommandProperty<T, U>
{
Func<T> CreateCommand { get; set; }
Func<T, U> ParseResponse { get; set; }
}
public interface IDeviceCommand
{
void SetCreateCommand<T, U>(Func<ICommandProperty<T, U>> cmd);
void SetParseCommand<T, U>(Func<ICommandProperty<T, U>> cmd);
Func<ICommandProperty<T, U>> GetCreateCommand<T, U>();
Func<ICommandProperty<T, U>> GetParseCommand<T, U>();
void Create(object someKnownObject);
T Parse<T>(object someKnownObject);
string Name { get; set; }
}
public class DeviceCommand : IDeviceCommand
{
public DeviceCommand(IDeviceCommandBuilder builder)
{
builder.SetCommands(this);
}
public void SetCreateCommand<T, U>(Func<ICommandProperty<T, U>> cmd)
{
throw new NotImplementedException();
}
public void SetParseCommand<T, U>(Func<ICommandProperty<T, U>> cmd)
{
throw new NotImplementedException();
}
public Func<ICommandProperty<T, U>> GetCreateCommand<T, U>()
{
throw new NotImplementedException();
}
public Func<ICommandProperty<T, U>> GetParseCommand<T, U>()
{
throw new NotImplementedException();
}
public void Create(object someKnownObject)
{
throw new NotImplementedException();
}
public T Parse<T>(object someKnownObject)
{
throw new NotImplementedException();
}
public string Name
{
get { throw new NotImplementedException(); }
set { throw new NotImplementedException(); }
}
}
public interface IDeviceCommandBuilder
{
void SetCommands(IDeviceCommand command);
}
public class DeviceCommandBuilder : IDeviceCommandBuilder
{
public void SetCommands(IDeviceCommand command)
{
command.SetCreateCommand<string,Uri>(.)
;
command.SetParseCommand(.);
}
}