How to implement a property in an interface - c#

I have interface IResourcePolicy containing the property Version. I have to implement this property which contain value, the code written in other pages:
IResourcePolicy irp(instantiated interface)
irp.WrmVersion = "10.4";
How can I implement property version?
public interface IResourcePolicy
{
string Version
{
get;
set;
}
}

In the interface, you specify the property:
public interface IResourcePolicy
{
string Version { get; set; }
}
In the implementing class, you need to implement it:
public class ResourcePolicy : IResourcePolicy
{
public string Version { get; set; }
}
This looks similar, but it is something completely different. In the interface, there is no code. You just specify that there is a property with a getter and a setter, whatever they will do.
In the class, you actually implement them. The shortest way to do this is using this { get; set; } syntax. The compiler will create a field and generate the getter and setter implementation for it.

You mean like this?
class MyResourcePolicy : IResourcePolicy {
private string version;
public string Version {
get {
return this.version;
}
set {
this.version = value;
}
}
}

Interfaces can not contain any implementation (including default values). You need to switch to abstract class.

The simple example of using a property in an interface:
using System;
interface IName
{
string Name { get; set; }
}
class Employee : IName
{
public string Name { get; set; }
}
class Company : IName
{
private string _company { get; set; }
public string Name
{
get
{
return _company;
}
set
{
_company = value;
}
}
}
class Client
{
static void Main(string[] args)
{
IName e = new Employee();
e.Name = "Tim Bridges";
IName c = new Company();
c.Name = "Inforsoft";
Console.WriteLine("{0} from {1}.", e.Name, c.Name);
Console.ReadKey();
}
}
/*output:
Tim Bridges from Inforsoft.
*/

but i already assigned values such that irp.WrmVersion = "10.4";
J.Random Coder's answer and initialize version field.
private string version = "10.4';

You should use abstract class to initialize a property. You can't inititalize in Inteface .

Related

How to get members of abstract class using reflection?

I have following:
var type = typeof(ExampleClass);
public abstract class ExampleClass
{
public string Name { get; set; }
public abstract class InternalExampleClass
{
public string InternalName { get; set; }
}
}
How can I get the value of Name, InternalName?
I tried to use type.GetFields() but it doesn't return InternalName
help me, please
I can't answer all points of your question. But I can give you an idea how to start.
You don't have access to constants, but there is a workaround. First, you need an instance of your abstract class in order to use reflection. Since you can't create an object of an abstract class, you need a class which inherits it. This class contains properties set to the value of your constants.
public class InheritedReportAPI : ReportAPI
{
public string constName { get; } = ReportAPI.Name;
public string constSignatureBase { get; } = ReportAPI.SignatureBase;
public string constEventsReportsDeleted { get; } = ReportAPI.Events.ReportsDeleted;
}
Then you can use Reflection to get names and/or values of these properties.
var inheritedReportApi = new InheritedReportAPI();
var propertyList = inheritedReportApi.GetType().GetProperties();
foreach(var property in propertyList)
System.Console.WriteLine($"{property.Name}: {property.GetValue(inheritedReportApi)}");
The result:
constName: reports
constSignatureBase: /report/reports
constEventsReportsDeleted: reports_deleted

When to use virtual data member in class?

I know what the use of virtual methods is, and how to declare them. But my question is: When should I declare a property as virtual?
For example:
public class Base
{
public virtual string lastName { get; set; }
}
As comments below this question state, data members are in fact methods, so you can declare them as virtual.
With properties you can add some validation later on, or implement events, for example when you implement INotifyPropertyChange interface.
Code from MSDN:
class MyBaseClass
{
public virtual string Name { get; set; }
}
class MyDerivedClass : MyBaseClass
{
private string name;
// Override auto-implemented property with ordinary property
// to provide specialized accessor behavior.
public override string Name
{
get
{
return name;
}
set
{
if (value != String.Empty)
{
name = value;
}
else
{
name = "Unknown";
}
}
}
}
Rules are the same, since property is, generally speaking, a syntactic sugar to hide get and set methods:
public class Base {
public virtual string LastName {
get; // this is method (.Net implements it for you)
set; // this is method (.Net implements it for you)
}
}
Imagine
Base b = ...
...
b.LastName = b.LastName + "x";
and compare, please, with Java which doesn't have properties:
b.setLastName(b.getLastName() + "x");
For the class in the question you may want to implment something like this:
public class Derived: Base {
public override string LastName {
get {
return String.IsNullOrEmpty(base.LastName)
? base.LastName
: base.LastName.ToUpper();
}
set {
if (null == value)
throw new ArgumentNullException("value")
base.LastName = value;
}
}

Get a variable from a class that inherits another

I have an arbitrary amount of classes, classThatInherits, anotherClassThatInherits, etc. that inherit classToBeInherited.
I then have a method, b, that needs to be able to access myValue from the classes that inherit classToBeInherited. How can I achieve this, without casting?
//This class will be inherited by other classes
public class classToBeInherited {
public bool isSomething { get; set; }
}
//This class with inherit 'classToBeInherited'
public class classThatInherits : classToBeInherited {
public int myValue { get; set; } //this needs to be accessable...
}
//...And so will this class
public class anotherClassThatInherits : classToBeInherited {
public int myValue { get; set; }
}
private class normalClass {
private void a() {
classThatInherits cti = new classThatInherits();
b(cti);
anotherClassThatInherits acti = new anotherClassThatInherits();
b(acti);
}
private void b(classToBeInherited c) {
//***
//get myValue from the classes that inherit classToBeInherited
//***
}
}
Move myValue to classToBeInherited:
public class classToBeInherited {
public bool isSomething { get; set; }
public abstract int myValue { get; set; }
}
Then in classThatInherits and anotherClassThatInherits use public override int myValue { get; set; } to implement that property.
Ofcorse, if myValue is needed in only some of the classes, then you can have virtual and not abstract property.
var a = c as anotherClassThatInherits;
if (a != null)
{
var myValue = a.myValue;
}
I don't know why you don't want to do casting, but it's very common to have code like above.
UPDATED
If you really don't want casting, you can use reflection (but you still need to know the type of anotherClassThatInherits)
var getter = typeof(anotherClassThatInherits).GetProperty("myValue").GetGetMethod();
var myValue = getter.Invoke(c, null);

Inheriting from an interface with properties of the same name

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; }
}
}

Interfaces property name differs from class to class

Here`s the question.
public abstract class A {}
public class B:A
{
public TypeF FieldB;
}
public class C:A
{
public TypeG FieldC;
}
public class TypeF:A { }
public class TypeG:A { }
I want to have interface ex: ITypeFG and to implement it in B and C BUT to have properties names FieldB and FieldC
interface ITypeFG
{
public A FieldFG; //But i want to have names TypeF in A and TypeG in B
}
Can this be done?
Thanks.
explicit interface implementation:
public class B : A, ITypeFG
{
public TypeF FieldB { get; set; } // please don't expose public fields...
A ITypeFG.FieldFG { get { return FieldB; } }
}
public class C : A, ITypeFG
{
public TypeG FieldC { get; set; }
A ITypeFG.FieldFG { get { return FieldC; } }
}
Note that if the interface has a setter, you'll need to cast:
public class B : A, ITypeFG
{
public TypeF FieldB { get; set; }
A ITypeFG.FieldFG { get { return FieldB; } set { FieldB = (TypeF)value; } }
}
public class C : A, ITypeFG
{
public TypeG FieldC { get; set; }
A ITypeFG.FieldFG { get { return FieldC; } set { FieldC = (TypeG)value; } }
}
Two points:
Interfaces in C# can't have fields, but they can have properties.
The desired feature isn't sensible: if clients would always have to know the "specific" name of the implemented interface-property to interact with an implementation, then it isn't much of an interface is it - it's little more than a marker.
As Marc Gravell suggests, a decent workaround is to use explicit implementations. If the client has a reference to the implementing object typed as the interface, they can use the "general" name of the property. If they have a specific reference (i.e. typed as the implementing type) , they can use the "specific" name (and won't be confused by the general name since they won't see it on IntelliSense, for example).
Sounds like you should treat the field names as data along with A. That way you can keep a common interface and only vary the content of what is returned:
class Data
{
public string Name {get;set;}
public A Value {get;set;}
}
interface ITypeFG
{
Data Field {get;}
}
class B : A, ITypeFG
{
public Data Field
{
get
{
return new Data {Name = "TypeF", Value = FieldB};
}
}
}
class C : A, ITypeFG
{
public Data Field
{
get
{
return new Data {Name = "TypeG", Value = FieldC};
}
}
}

Categories

Resources