Lets say I have the following class:
public class Provider
{
...
public sealed class Slice
{
public readonly double firstName;
public readonly double secondName;
public readonly double thirdName;
...
}
...
}
This class is used to hold a sliding time series and the contained Slice class is the return value. (Provider.Last property returns the latest instance of Slice).
I need to get the value of the properties of that latest returned Slice class by name of the property.
PropertyInfo secondNameProperty = Provider.Last.GetType().GetProperty("secondName");
double secondNameValue = (double)secondNameProperty.GetValue(Provider.Last, null);
GetProperty returns null. How can I do this?
Look at your Slice class:
public sealed class Slice
{
public readonly double firstName;
public readonly double secondName;
public readonly double thirdName;
...
}
Those aren't properties. They're fields. Either make them properties, or use Type.GetField() instead. Using properties would generally be a better idea, IMO, and needn't be hard. For example, if you just wanted to make them publicly read-only, you could use:
public sealed class Slice
{
public double FirstName { get; private set; }
public double SecondName { get; private set; }
public double ThirdName { get; private set; }
...
}
Alternatively you could declare read-only fields directly, and then expose them via properties. It's a bit more work than using automatically implemented properties, but it removes the potential for setting the property within Slice itself.
(As an aside, do you really have a firstName field of type double? Odd.)
As Jon Skeet says, these aren't properties. Readonly properties would look like this
public sealed class Slice
{
public double FirstName { get; private set }
public double SecondName { get; private set }
public double ThirdName { get; private set }
...
}
or
public sealed class Slice
{
private double _firstName;
public double FirstName { get { return _fristName; } }
private double _secondName;
public double SecondName { get { return _secondName; } }
private double _thirdName;
public double ThirdName { get { return _thirdName; } }
...
}
You can use GetMember() - Members include properties, methods, fields, events, and so on.
Or use Jon Skeet's answer.
Note, the if you use GetField() and later change your fields to properties, GetMember() will continue to find the Field or Property in question without refactoring the code, whereas GetField() will return null.
http://msdn.microsoft.com/en-us/library/xdtchs6z.aspx
Related
I have the following structure:
public class LogicStatement : ILogicStatement
{
public string TestLogic { get; set; }
public string CompareLogic { get; set; }
public string Operator { get; set; }
public string Expression();
public bool Value();
}
public class Test : ITest
{
public int TestId { get; set; }
public int LiteralId { get; set; }
public string TestName { get; set; }
public string TestText { get; set; }
public string TestDisplayName { get; }
**public ILogicStatement LogicStatement { get; set; }**
public string Expression { get; set; }
public bool Value { get; set; }
}
public class Literal : ILiteral
{
some property members...
**public List<ITest> Tests {get; set;}**
some method members...
}
Note that the class Test has a member of type LogicStatement, and the class Literal has a member of type List.
Note also that all classes have properties and methods that share the same name: Expression, Value, Expression(), Value().
The value of Expression and Value (properties and methods) depend on values in the LogicStatement class.
Throughout the whole project, I use the Interface Type for to instantiate each object to adhere with Dependency Inversion. To support this, I use a factory-like design to create new instances of Test and LogicStatement.
Example:
public static class Factory
{
public static ILogicStatement CreateLogicStatement()
{
return new LogicStatement();
}
public static ITest CreateTest()
{
return new Test(CreateLogicStatement());
}
public static List<ITest> CreateTests()
{
return new List<ITest>();
}
//repeat the same for evey other class.
}
My goal is to have Expression() and Value() be calculated only once in the bottom level class (LogicStatement), and somehow get transfered to their counterpart properties in the higher level classes.
I'm getting the data from Dapper and it looks like all the nested objects are returned from the Dapper module correctly with the same nested structure I intended, and with the right values for all of their members. All of them but Expression, Expression(), Value, Value() are null.
my constructors look like this:
public LogicStatement()
{
Expression();
Value();
}
public Test(ILogicStatement logicStatement)
{
_logicStatement = logicStatement;
Expression = _logicStatement.Expression();
Value = _logicStatement.Value();
}
public Literal(ITest test)
{
_test = test;
Expression = _test.Expression;
Value = _test.Value;
}
and my main:
List<ILiteral> literals = Factory.CreateLiterals();
List<ITest> tests = Facotry.CreateTests();
List<ILogicStatement> logicStatements = Factory.CreateLogicStatements();
literals = GetDataFromDapper();
This last line seems to assign correct values to all other members on all hierarchies. But I cannot get Expression and Value to be anything other than null.
If I test LogicStatement.Expression() and LogicStatement.Value() standalone, they do return the expexted values. but starting at the first parent class Test, these properties are all null.
I think I'm doing something wrong in the way i'm instantiating my objects. Primarily because I'm not sure i understand basic best practices to write constructors.
Maybe I the desired behavior should be implemented through events, where the Test and Literal classes subscribe to changes in the Expression() and Value() methods (or rather to what calculates them). But I never used events and I'd like to know if this fundamentally can be acheived without them first.
My question: How do I make the Expression() Value() at the bottom level class "Fire up" whenever LogicStatement is instantiated, and then have the Expression and Value properties be assigned accordingly as a result.
In other words, I want the following to always be true:
test[i].Expression == literal[i].Expression == LogicStatement[i].Expression()
I'm a beginner in OOP. So any fundamental explanation is welcome.
As you are new to object oriented programming I would start with the basics and leave factories and adhering with Dependency Inversion and the interfaces away for later.
You could tell Dapper to split joined tables into multiple entities (see https://www.learndapper.com/relationships), but for learning OOP I would start doing everything manually.
Your class design does not look proper to me yet. Not sure what Expression and Value of the LogicStatement are, but if they are calculations based on the other properties, I would implement them as (just to show off with complicated words) lazy initialized cached getter properties that are invalidated in the setters of the relevant properties. That ensures you only calculate them once for as many reads you like but recalculate them on first read after one or multiple properties have been updated.
public class LogicStatement {
private string _testLogic;
private string _compareLogic;
private string _operator;
private string? _expression;
private bool? _value;
public LogicStatement(string testLogic, string compareLogic, string #operator) {
_testLogic = testLogic;
_compareLogic = compareLogic;
_operator = #operator;
}
public string TestLogic {
get {
return _testLogic;
}
set {
_testLogic = value;
InvalidateCachedValues();
}
}
public string CompareLogic {
get {
return _compareLogic;
}
set {
_compareLogic = value;
InvalidateCachedValues();
}
}
public string Operator {
get {
return _operator;
}
set {
_operator = value;
InvalidateCachedValues();
}
}
public string Expression {
get {
string? result = _expression;
if (result is null) {
_expression = result = BuildExpression();
}
return result;
}
}
public bool Value {
get {
bool? result = _value;
if (result is null) {
_value = result = EvaluateValue();
}
return result.Value;
}
}
private void InvalidateCachedValues() {
_expression = null;
_value = null;
}
private string BuildExpression() {
//Your logic goes here
throw new NotImplementedException();
}
private bool EvaluateValue() {
//Your logic goes here
throw new NotImplementedException();
}
}
Sorry, it got a bit bigger with the full properties.
In the other classes I would not copy the Value and the Expression but simply remove these properties as anybody can easily access them through the LogicStatement property:
public class Test {
public Test(int testId, int literalId, string testName, string testText, string testDisplayName, LogicStatement logicStatement) {
TestId = testId;
LiteralId = literalId;
TestText = testText;
TestDisplayName = testDisplayName;
LogicStatement = logicStatement;
}
public int TestId { get; }
public int LiteralId { get; }
public string TestName { get; }
public string TestText { get; }
public string TestDisplayName { get; }
public LogicStatement LogicStatement { get; }
}
and the Literal could look like this (I got a bit confused whether this class has one Test or a list of them, I stick to your constructor + properties that hint in the direction of a single one):
public class Literal {
private Test _test;
public Literal(string property1, int property2, Test test) {
Property1 = property1;
Property2 = property2;
_test = test;
}
public string Property1 { get; }
public int Property2 { get; }
public string Expression => _test.LogicStatement.Expression;
public bool Value => _test.LogicStatement.Value;
}
As you decided not to expose the Test in the Literal it makes sense to provide Expression and Value, otherwise they could also be removed (or kept for convenience).
Issue origin: I have a generic component to display data. The data may come from different data models. To unify the access inside the component I created one interface IOne that gets implemented by all classes. In order to abstract the data access layer from the application I'm using interfaces for each data model. So each data display model implements the IOne interface and additionally one of the data model interfaces.
The interfaces:
public interface IOne
{
public int idNameOne { get; set; }
}
public interface DataModelOne
{
public int anotherNameForId{ get; set; }
}
In my class I want both members to be satisfied by one single property. My current solution is as follows:
public class Implementation : IOne, DataModelOne
{
private int _id;
public idNameOne { get { return _id; } set { _id = value; } }
public anotherIdName { get { return _id; } set { _id = value; } }
}
Is there any way to declare that one property satisfies both members? What would be a clean solution for this?
No, there's no other way than what you are doing. I'd however clean up the code (and do proper casing), by removing the backing field (and use one auto-property) and only have the other one reference the first... something like:
public class Implementation : IOne, IDataModelOne
{
public int IdNameOne { get; set }
public int AnotherIdName { get => IdNameOne; set => IdNameOne = value; }
}
(notice I've used the proper casing for the properties... should be the same casing on the interfaces too... also named IDataModelOne correctly, with an I prefix)
To avoid having both on the public API, you should usually use "explicit interface implementation" for this, for example:
public class Implementation : IOne, DataModelOne
{
public int idNameOne { get; set; }
int DataModelOne.anotherNameForId
{
get => idNameOne;
set => idNameOne = value;
}
}
or
public class Implementation : IOne, DataModelOne
{
public int Id { get; set; }
int IOne.idNameOne
{
get => Id;
set => Id = value;
}
int DataModelOne.anotherNameForId
{
get => Id;
set => Id = value;
}
}
If I really had to do this I would make the idNameOne property an auto property with anotherIdName's getter and setter referring to that property.
public class Implementation : IOne, DataModelOne
{
public idNameOne { get; set; }
public anotherIdName { get { return idNameOne; } set { idNameOne = value; } }
}
It's a little bit cleaner and show the intention a little better too.
My goal is to make a static object that won't change, using a base class's member variables and abstract methods, as there will be multiple of these type of objects.
This is an example of what I want to do:
public abstract class BaseThing
{
public string Name { get; set; }
public string Description { get; set; }
public decimal Cost { get; set;}
public abstract void MethodThatDoesThings();
}
Then I want to have a derived object that has default values of those base variables, something like this (obviously doesn't work) :
public class DerivedThing : BaseThing
{
Name = "Name1";
Description = "Description1";
Cost = 1.00;
public override void MethodThatDoesThings()
{
//Actually does things
}
}
Is something like this possible without using a constructor? Not that I'm against using them, I'm just genuinely curious. Right now I feel as though my only option is to create many static classes that have the same properties.
No, you should implement a constructor for derived class to set default values. If you want to set default values, you can do it like this;
public class DerivedThing : BaseThing
{
public DerivedThing(string name = "Name", string description = "Description1", decimal cost = 1.0)
{
Name = name;
Description = description;
Cost = cost;
}
public override void MethodThatDoesThings()
{
}
}
I have a series of classes used to represent identifiers in my project that are supposed to have a specific string storage format. I don't have control on this format.
The classes are pure containers, they don't do anything. The storage format is of the form "CLASSSTYPE|key1|key2|key3|...|keyN". Each "key" can be mapped to one property of the class.
Right now the FromStorageString and ToStorageString functions look like this:
public class SomeTypeId : IObjectId
{
public static string ToStorageString(SomeTypeId id)
{
return string.Format("{0}|{1}|{2}", typeof(SomeTypeId).Name, MyIntKey, MyStringKey);
}
public static SomeTypeId FromStorageString(IdReader source)
{
int intKey = source.Retrieve<int>();
string stringKey = source.Retrieve<string>();
return new SomeTypeId(intKey, stringKey);
}
public int MyIntKey { get; private set; }
public string MyStringKey { get; private set; }
public SomeTypeId(int intKey, string stringKey)
{
MyIntKey = intKey;
MyStringKey = stringKey;
}
}
We are checking the From/To consistency in unit tests, but I feel there should be a way to simplify the set up and perform the check a compile-time.
What I had in mind is something like this:
[Storage("MyIntKey", "MyStringKey")]
public class SomeTypeId : IObjectId
{
private SomeTypeId() {}
public int MyIntKey { get; private set; }
public string MyStringKey { get; private set; }
public SomeTypeId(int intKey, string stringKey)
{
MyIntKey = intKey;
MyStringKey = stringKey;
}
}
But first I don't know how to do this with the no parameters constructor and the property setters staying private. I am reluctant to have them public.
Second this approach is not robust to property name change and typos because the property names in the attribute are strings.
Should I expose the setters and private constructor ?
Is there a better way of doing this ?
In C# and its cousin languages, we always use
public string SomeString { get; set;}
But you can also use ( I found this out only recently and while fooling around with the compiler )
public string SomeString { set; get; }
I do not have any formal training in programming and everything is self-tought. I have been using { get; set; } without any thought just like we use 1 + 1 = 2 Is the order of { get; set; } just a convention or is it necessary to maintain this order or is it some remnant of a bygone era of C history like the way we define conventional electric current flowing from positive to the negative terminal when it is actually the other way around?
It is purely a convention. It makes no difference which order they appear in.
There is no difference.
It is exactly as if you had implemented the getter first in your class body, and the setter after it. The functions would still do exactly the same:
public String getSomeString() { return someString; }
public void setSomeString(String value) { someString=value; }
Whether they are written in that order
public void setSomeString(String value) { someString=value; }
public String getSomeString() { return someString; }
or the opposite. Wouldn't they?
I would however suggest to stick to one order in your code. Less entropy is always better :)
There is no difference.
According to the C# Language Specification http://msdn.microsoft.com/en-us/library/ms228593.aspx, 10.7.2 Accessors (page 324)
The accessor-declarations of a property specify the executable
statements associated with reading and writing that property.
accessor-declarations:
get-accessor-declaration set-accessor-declaration
set-accessor-declaration get-accessor-declaration
As shown it states either order has the same effect
Internally Get and Set are methods like this
private PropertyType Get() {}
private Set(value as PropertyType) {}
Since order of declaration of methods is not important, same case goes here.
MSDN:
The body of the get accessor is similar to that of a method. It must return a value of the property type.
The set accessor is similar to a method that returns void. It uses an implicit parameter called value, whose type is the type of the property.
{ get; set; } is just a shortcut so you don't have to write getters and setters for every field you want to expose. It's the same as when you write
public string GetSomeString() { }
public void SetSomeString(string value) { }
Does it matter, which one you write first? Of course not.
Just a convention you can use any of these when defining parameters:
public string SomeString { get; set; }
public string SomeString2 { set; get; }
public string someString2;
public string SomeString21
{
get { return someString2; }
set { someString2 = value; }
}
public string SomeString22
{
set { someString2 = value; }
get { return someString2; }
}
public string SomeString23
{
set { someString2 = value; }
}
public string SomeString24
{
get { return someString2; }
}
As others have already pointed out, there is no difference and it is just a convention. But to prove that up, you can see how compiler actually treats your code, given the following:
public class C
{
public string SomeString { get; set;}
public string SomeString2 { set; get; }
}
This will be treated as:
public class C
{
[CompilerGenerated]
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private string <SomeString>k__BackingField;
[CompilerGenerated]
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private string <SomeString2>k__BackingField;
public string SomeString
{
[CompilerGenerated]
get
{
return <SomeString>k__BackingField;
}
[CompilerGenerated]
set
{
<SomeString>k__BackingField = value;
}
}
public string SomeString2
{
[CompilerGenerated]
get
{
return <SomeString2>k__BackingField;
}
[CompilerGenerated]
set
{
<SomeString2>k__BackingField = value;
}
}
}
As you can see, in both of them a new BackingField is generated by compiler and the body of two properties are same exactly.
The reference.