I have an interface that looks like this:
interface IName
{
string Name { get; set; }
}
and a Class like this:
public class ClassN
{
public int N { get; set; }
}
N in this Class N is an int, and the interface requires a string Name.
I want the int N to be converted to string and to be counted as Name in the interface.
So that when I do T.name I get the .N.toString().
Is this possible?
Name = N.ToString();
Example:
N = 2; than Name = 2; (but as string)
You can use an explicit interface implementation:
public class ClassN : IName
{
string IName.Name
{
get { return N.ToString(); }
set{ if(int.TryParse(value, out int i)) N = i; }
}
public int N { get; set; }
}
You can use generic configuration.
interface IName<T>
{
T Name { get; set; }
}
If you want a casting related configuration, you can use object.
interface IName
{
object Name { get; set; }
}
if N is the name better you can set property type as string instead of int.
Reason, in this way you can take string and number both as input.
I am available here Find me
Related
I have many entities that use a UserId property of the same type.
Can I define a type (string or int, ...) that I can easily change as a variant for all?
Example:
public class Entity_One
{
public DefineMyType UserId { get; set; }
public string Property_Entity_One { get; set; }
}
public class Entity_Two
{
public DefineMyType UserId { get; set; }
public string Property_Entity_Two { get; set; }
}
const DefineMyType = string;
// or const DefineMyType = int;
// or const DefineMyType = Guid;
Constants can't be used like that.
Preprocessor may be used.
But we can use a generic:
public abstract class AbstractID<T>
{
static protected T Last = default;
public T Value { get; protected set; } // or perhaps init only with C# 9
}
Thus we can define some specialized IDs like:
public class NumberID<T> : AbstractID<T> where T : struct, IComparable, IFormattable
{
public NumberID()
{
Value = (T)( (dynamic)Last + 1 );
Last = Value;
}
}
public class GuidID : AbstractID<Guid>
{
public GuidID()
{
Value = Guid.NewGuid();
Last = Value;
}
}
public class StringID : AbstractID<string>
{
private string Generate()
{
return ...
}
public StringID()
{
Value = Generate();
Last = Value;
}
}
Then we can set the "default" ID type:
public class ManagedID : NumberID<int>
{
}
Or:
public class ManagedID : GuidID
{
}
Therefore we can easily change ManagedID for all code using it.
It only requires to change the ancestor class in the declaration.
And now that works:
public class EntityOne
{
public ManagedID UserId { get; } = new ManagedID();
public string PropertyEntityOne { get; set; }
}
public class EntityTwo
{
public ManagedID UserId { get; } = new ManagedID();
public ManagedID EntityOneId { get; }
public string PropertyEntityTwo { get; set; }
public EntityTwo(EntityOne one)
{
EntityOneId = one.UserId;
}
}
Test
var entity1 = new EntityOne();
var entity2 = new EntityOne();
var entity3 = new EntityTwo(entity1);
Console.WriteLine(entity1.UserId.Value);
Console.WriteLine(entity2.UserId.Value);
Console.WriteLine(entity3.UserId.Value + $" ({entity3.EntityOneId.Value})");
Result with an integer
1
2
3 (1)
Result with a GUID
3a189122-60fd-4dc5-9d7f-3cc4c83375f9
37a9c7de-8ed5-4d02-a1b9-f414db051335
2de962d6-cc91-4e78-b3dc-28acb0ba7f3b (3a189122-60fd-4dc5-9d7f-3cc4c83375f9)
Warning
Here, the use of numbers is very basic and not really reliable, especially beyond a local machine and after stopping the execution of the current process. Thus persistence somewhere of the last value is required for a real database, like in a config file or whatever.
GUID vs INT IDENTITY
Guid vs INT - Which is better as a primary key?
Int for identity/primary key and Guid for public identifier, best practices?
I've got a function with List<> set as the parameter, which looks something like this:
private Double CalculateConsumption(List<GasConsumRecord> gasRecord)
{
...
foreach (var record in gasRecords){
var x = record.Counter;
var y = record.Pressure;
...
}
...
}
GasConsumRecord class has more properties but in this function I use only 2.
And I've got another class - AirConsumRecord which has the same 2 properties but other properties are different. Both classes have only properties, but no methods.
My question is: How can I use the same method for two different class List<> as parameter?
Thanks in advance.
You'll need your classes to implement the same interface, or derive from the same base class, which contains these two properties, then use a generic method with a type constraint:
If you use interfaces:
public interface IRecord {
int Counter { get; set; }
int Pressure { get; set; }
}
public class GasConsumRecord : IRecord {
public int Counter { get; set; }
public int Pressure { get; set; }
}
public class AirConsumRecord : IRecord {
public int Counter { get; set; }
public int Pressure { get; set; }
}
private Double CalculateConsumption<T>(List<T> records)
where T : IRecord
{
foreach (IRecord record in records){
var x = record.Counter;
var y = record.Pressure;
}
}
I have the following abstract class:
abstract class ContactQueue
{
public abstract DateTime period {
get; set; }
public abstract String type { get; set; }
public abstract String toString();
}
Now one of the sub classes of this class is the following:
class GeneralPercentageQueue : ContactQueue
{
public GeneralPercentageQueue(DateTime period)
{
this.period = period;
}
public int phone_answer_total {get; set;}
public int phone_answer_percentage_8025 { get; set; }
public int web_answer_percentage_8030 { get; set; }
public int web_answer_percentage_total { get; set; }
public int mail_answer_percentage { get; set; }
public override DateTime period { get; set; }
public override string type { get; set; }
public override string toString()
{
return period.ToString();
}
}
Now since i have several subclass of the abstract class i have created a list that can contain them all i want to loop through that list and access one of the specefic fields to do this i have attempted the following:
foreach(ContactQueue cq in p.GetGeneralEmailPercentageData(start,end))
{
foreach (ContactQueue contactqueue in finalDataList)
{
if (cq.period == contactqueue.period)
{
(GeneralPercentageQueue)contactqueue.mail_answer_percentage = (GeneralPercentageQueue)cq.mail_answer_percentage;
}
}
}
However im getting an error that there is no such field in the object ContactQueue
So how do i access it?
As others have mentioned you're missing parenthesis which is causing the error.
Instead you can use OfType(T) to filter the collections to only the type you want to compare.
foreach(GeneralPercentageQueue cq in p.GetGeneralEmailPercentageData(start,end)
.OfType<GeneralPercentageQueue>())
{
foreach (GeneralPercentageQueue contactqueue in finalDataList.OfType<GeneralPercentageQueue>())
{
if (cq.period == contactqueue.period)
{
contactqueue.mail_answer_percentage = cq.mail_answer_percentage;
}
}
}
This will prevent exceptions at runtime for mismatched types.
You need to add parentheses:
((GeneralPercentageQueue)contactqueue).mail_answer_percentage = ...;
You need to add paranthesis what is happening is the following:
contactqueue.mail_answer_percentage is calledcast is called on contactqueue.mail_answer_percentage to type GeneralPercentageQueue
Because the property mail_answer_percentage is not a property in type ContactQueue the first call fails, and you get the error that mail_answer_percentage isn't a property in ContactQueue
so your code should look like
((GeneralPercentageQueue)contactqueue).mail_answer_percentage =
((GeneralPercentageQueue)cq).mail_answer_percentage;
This question already has answers here:
Error 7, argument 1: cannot convert from ' ' to ' ' [duplicate]
(3 answers)
Closed 9 years ago.
I am trying to customize List. I have it mostly figured out but am coming across a problem. Here is the code I am working with:
public class MyT
{
public int ID { get; set; }
public MyT Set(string Line)
{
int x = 0;
this.ID = Convert.ToInt32(Line);
return this;
}
}
public class MyList<T> : List<T> where T : MyT, new()
{
internal T Add(T n)
{
Read();
Add(n);
return n;
}
internal MyList<T> Read()
{
Clear();
StreamReader sr = new StreamReader(#"../../Files/" + GetType().Name + ".txt");
while (!sr.EndOfStream)
Add(new T().Set(sr.ReadLine())); //<----Here is my error!
sr.Close();
return this;
}
}
public class Customer : MyT
{
public int ID { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
public class Item : MyT
{
public int ID { get; set; }
public string Category { get; set; }
public string Name { get; set; }
public double Price { get; set; }
}
public class MyClass
{
MyList<Customer> Customers = new MyList<Customer>();
MyList<Item> Items = new MyList<Item>();
}
In the code, you can see that I am trying to create a customize List.
Here you also see two of the many classes that I have. All of the classes have an ID.
All of the classes are matched with a custom List.
The problem seems to be in MyList<T>.Read() - Add(new T().Set(sr.ReadLine()));
Lastly, I get that MyT can not be converted to T. I need to know how to fix it.
The Set method returns the type MyT instead of the specific type. Make it generic so that it can return the specific type:
public T Set<T>(string Line) where T : MyT {
int x = 0;
this.ID = Convert.ToInt32(Line);
return (T)this;
}
Usage:
Add(new T().Set<T>(sr.ReadLine()));
Or cast the reference back to the specific type:
Add((T)(new T().Set(sr.ReadLine())));
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 .