I have the following class:
public class OrderRule {
public OrderDirection Direction { get; }
public String Property { get; }
}
I created an Unit Test using XUnit as follows:
public void TryParse_ParseAscendingOrderRule() {
OrderRule expect = new OrderRule("name", OrderDirection.Ascending);
OrderRule result = factory.GetOrderRule("type1");
Assert.Equal(result, expect);
}
I know expect and result have the same Direction and Property values but I still get False on my test ... I suppose this is because they are not the same instance ...
Do I really need to compare the Direction and Property as follows?
Assert.True(result.Property == expect.Property && expect.Property == expect.Property );
This can become really long when the objects have many properties ...
Or is there a better way to do this?
If it is not necessary for OrderRule to be a class then make it a struct which by default implements value equality. There is also a whole MSDN page about value equality which might help you.
Related
I'm pretty new to programming, and I'm teaching myself. Any and all help is appreciated, but please be understanding -- I don't really know what I'm doing that well. Also, this is the first question I've ever posted on SO (I sure have read a lot of other people's, so thanks for all that), so if I need to modify anything about how I'm asking, please let me know. Thanks!
I'm working on creating a Xamarin application in Visual Studio.I created a mock database to serve mock information to my application. The MockDatabase file is a POCO with static lists to hold the information. There are 11 lists for the models that I created that will eventually map to the SQLite database file I'm planning to use in the future. Here's a snapshot of the file:
public class MockDatabase : IDataStore
{
public static List<tblAddress> Addresses { get; set; }
public static List<tblCrew> Crews { get; set; }
public static List<tblCustomer> Customers { get; set; }
public static List<tblEmployee> Employees { get; set; }
//etc...
public MockDatabase(bool createMockData = false)
{
if (createMockData)
{
Addresses = Addresses ?? MockData.MockAddresses();
Crews = Crews ?? MockData.MockCrews();
Customers = Customers ?? MockData.MockCustomers();
Employees = Employees ?? MockData.MockEmployee();
//etc...
}
}
The static modifier does what I want, that even if I initialize multiple instances of the class, each of them points to the same static instance of the list. So, the problem that I'm having with using static lists is that it works too well. When I run my unit tests in a consecutive run, the tests are getting the data that a previous test set, which meant I had to rewrite the tests to account for this. I solved the problem by calling MockDatabase.Addresses = new List<tblAddress>(); in my test initialization, but I really wanted to use something that would work more broadly, and not need to be specialized for each test class that I'm creating.
Here's what I had written:
[TestClass]
public class AddressRepositoryTests
{
[TestInitialize]
public virtual void SetUp()
{
MockDatabase.Addresses = new List<tblAddress>();
}
But what I was trying to accomplish was to have the MockDatabase use some reflection to find all lists within itself and reset their value. I tried a number of variations on the following code, but I couldn't find anything that worked.
[TestClass]
public class AddressRepositoryTests
{
[TestInitialize]
public virtual void SetUp()
{
(new MockDatabase()).ClearDatabase();
}
public void ClearDatabase()
{
var properties = typeof(MockDatabase).GetProperties();
foreach (var property in properties)
{
if (property.PropertyType == typeof(IList<BaseModel>))
{
property.SetValue(this, null);
}
}
}
I put a break point inside the if statement and tried a number of different code variations, and nothing ever returned true.
Thanks for any help!
Edit
I don't know how to use the generic List<T> in the middle of a method. Sticking it into the line produces the compiler error "The type or namespace T could not be found..."
if (property.PropertyType == typeof(IList<T>)) //Will not compile
I also tried comparing against List<object>, but that fails too.
if (property.PropertyType == typeof(IList<object>)) //Fails
Could you try changing ClearDatabase function as below:
public void ClearDatabase()
{
var properties = typeof(MockDatabase).GetProperties();
foreach (var property in properties)
{
if (property.PropertyType.Name == typeof(List<>).Name || property.PropertyType.Name == typeof(IList<>).Name)
{
property.SetValue(this, null);
}
}
}
Consider the following code:
public interface IIdentifiable<T>
{
T Id { get; set; }
}
public interface IViewModel
{
}
public class MyViewModel1 : IViewModel, IIdentifiable<int>
{
public string MyProperty { get; set; }
public int Id { get; set; }
}
public class MyViewModel2 : IViewModel, IIdentifiable<string>
{
public string MyProperty { get; set; }
public string Id { get; set; }
}
I also have class that operates with ViewModels:
public class Loader<T> where T: IViewModel
{
public void LoadData()
{
/*some important stuff here*/
if (typeof(IIdentifiable<??>).IsAssignableFrom(typeof(T)))
{ // ^- here's the first problem
data = data.Where(d => _dataSource.All(ds => ((IIdentifiable<??>) ds).Id != ((IIdentifiable<??>) d).Id)).ToList();
} // ^---- and there the second ----^
/*some important stuff here too*/
}
}
Now, as you can see, viewmodels that I have might implement the IIdentifiable<> interface. I want to check that, and if it's true,
I want to make sure my data list does not contains any entry that are already present in my _dataSourse list.
So I have 2 questions:
I don't know what IIdentifiable<> has in its generic parentheses, it might be int, string or even GUID.
I tried typeof(IIdentifiable<>).IsAssignableFrom(typeof(T)) which is the correct syntax, yet it always returns false.
Is there a way to check whether T is IIdentifiable<> without knowing the exact generic type?
If there is an answer for the first question, I would also like to know how can I compare the Id fields without knowing their type.
I found this answer quite useful, yet it doesn't cover my
specific case.
I know that I probably can solve that problem if I make my Loader<T> class a generic for two types Loader<T,K>, where K would be the
type in IIdentifiable<>, yet I would like to know if there are other solutions.
P.S. In addition to my first question: I'm also curious why one can write something like this typeof(IIdentifiable<>).IsAssignableFrom(typeof(T)) if it returns false when the generic type of IIdentifiable<> is not specified?
Edit: I guess, in hindsight, I understand why I can't write the code this bluntly - because there's might be the collection ICollection<IViewModel> where the entries implement different types of IIdentifiable<> (or don't implement it at all), and the check like that would fail awkwardly. Yet maybe there is a way to do something like that with some restrictions, but without creating second generic parameter to my Loader?
Try add two methods to your Loader<T>:
public bool CanCast<TId>()
{
var identifiableT = typeof(IIdentifiable<>).MakeGenericType(typeof(TId));
return identifiableT.IsAssignableFrom(typeof(T));
}
public IEnumerable<IIdentifiable<TId>> Filter<TId>(IEnumerable<T> data)
{
return data.Where(d => _dataSource.All(
ds => !((IIdentifiable<TId>) ds).Id.Equals(((IIdentifiable<TId>) d).Id)));
}
Then in LoadData
if (CanCast<int>())
data = Filter<int>(data);
else if (CanCast<Guid>())
data = Filter<Guid>(data);
// and so om
Well, I would suggest you to always use a string for identification. You can convert int and guid to a string. And if you want to ensure proper type is used then you can prefix the string with type information.
However, I do think that the performance of you algorithm would be very poor as you wouls essentially loop 2 containers so it would be O(n * m).
Thus it would be best to either do appropriate SQL query if both sources are from the database or use a dictionary if you do it in code. Alternatively if data is properly sorted, you could find duplicates more efficiently.
By the way generics are quite limited in C#. Sometime using ˋFunc<>ˋ could help but even then you have to provide extra information to the algorithm.
We should address your question in two steps (because there really are two problems to solve here).
First, make following change to your interface IIdentifiable<T>
public interface IIdentifiable<T>
where T : IEquatable<T>
{
T Id { get; set; }
}
This will ensure that you can compare Id properties correctly.
Secondly, in your LoadData() method, change the if statement to
if (T is IIdentifiable<T>)
{ // ^- here's the first problem
data = data.Where(d => _dataSource.All(ds => ((IIdentifiable<T) ds).Id != ((IIdentifiable<T) d).Id)).ToList();
}
I have the following object (class).
namespace Temp.Models
{
public class CurrentClass
{
private double _firstCoefficient;
private double _secondCoefficient;
public double FirstCoefficient
{
get { return _firstCoefficient; }
set { _firstCoefficient= value; }
}
public double SecondCoefficient
{
get { return _secondCoefficient; }
set { _secondCoefficient= value; }
}
}
}
The following class utilizes the above object and therefore initializes the object as follows:
namespace Temp.Models
{
public class MainClass
{
private CurrentClass _currentClass = new CurrentClass();
public CurrentClass CurrentClass
{
get { return _currentClass; }
set { _currentClass = value; }
}
}
}
At some point if certain conditions are met I would define the variables as follows:
MainClass currentObject = new MainClass();
//if conditions are met
currentObject.CurrentClass.FirstCoefficient = 0;
currentObject.CurrentClass.SecondCoefficient = 5;
But what if the conditions are never met and I never define the above variables. How and/or what is the best way to check if the object was never defined?
I can do the following check:
if(currentObject.CurrentClass.FirstCoefficient != 0 && currentObject.CurrentClass.SecondCoefficent != 0)
But the values can be defined as 0...So I am not sure how to go about this.
Any help is much appreciated!
These are some principles that can be used for solving the problem with description, samples and brief evaluation/opinion.
1. Parametrization through constructors
According to OOP principles, a constructor is method used to initialize an object to a valid state. The concept of immutability takes this even further, disallowing any changes, completely avoiding invalid state.
There is also a possibility of compromise where the API of an object disallows invalid states.
With this concept, you would arrive to:
namespace Temp.Models
{
public class CurrentClass
{
public double FirstCoefficient { get; private set; }
public double SecondCoefficient { get; private set; }
public CurrentClass(double firstCoefficient, double secondCoefficient)
{
FirstCoefficient = firstCoefficient;
SecondCoefficient = secondCoefficient;
}
// if mutability is required - this is needless as the constructor is
// the same but if there was more complex state, methods like this would make
// sense, mutating only parts of the state
public void SetCoefficients(double firstCoefficient, double secondCoefficient)
{
FirstCoefficient = firstCoefficient;
SecondCoefficient = secondCoefficient;
}
}
}
Summary:
Each instantiation of CurrentClass is always in a valid state, avoiding a lot of consistency checks (improved encapsulation)
It takes more code to write (but you save a lot of other code due to the previous point)
You need to know the coefficients beforehand.
2. Using nullable types
Nullable types add the "additional" value to types, the "undefined" state. Reference types (class) are nullable by design while value types (struct) need to be marked nullable, either as Nullable<T> or with the shorthand T?.
This then allows the objects be in invalid state and be specific about it. This goes to the other end of consistency scale from immutability as an object with multiple nullable fields has many invalid states.
Sample code:
namespace Temp.Models
{
public class CurrentClass
{
public double? FirstCoefficient { get; set; }
public double? SecondCoefficient { get; set; }
}
}
Now this gets instantiated quite nicely and can be changed on the fly:
public CurrentClass CreateCurrentClass()
{
var currentClass = new CurrentClass { FirstCoefficient = 1.0 };
var secondCoefficient = RetrieveSecondCoefficient();
currentClass.SecondCoefficient = secondCoefficient;
return currentClass;
}
You'll however need validity checks everywhere the object is used.
public bool IsValid(CurrentClass currentClass)
{
// what if FirstCoefficient has value and SecondCoefficient doesn't,
// is that always an invalid state?
return currentClass.FirstCoefficient.HasValue
&& currentClass.SecondCoefficient.HasValue;
}
Summary:
Very little code is needed to have a DTO up and running
A lot of consistency checks (and related brain pain) are required to work with such model
Encapsulation is lacking - any method taking CurrentClass can alter its validity, therefore making the previous point even worse. This can be eased by usage of read-only interface passed where read-only access is required.
Summing up
There are many other means that usually lay in between the two aforementioned approaches. For example you can use one validity flag (SergeyS's response) per object and ease on the external validity checks but having more code in the class and the need of deeper thinking.
Personally, I prefer immutability. It's more monkey code to write but will definitely pay off down the road thanks to the clean design.
A complex system without immutability is very hard to reason about without extensive knowledge. This is especially painful when working in a team - usually each person only knows a part of the codebase.
The sad thing is that it's not always possible to have evertything immutable (e.g. viewmodels): then I tend to convert objects to an internal immutable model as soon as it's possible.
Given what you already wrote, I would add Initialize() method and Initialized property into your MainClass class. Something similar to this:
public class MainClass
{
private CurrentClass _currentClass = new CurrentClass();
public CurrentClass CurrentClass
{
get { return _currentClass; }
set { _currentClass = value; }
}
public bool Initialized {get; private set;}
public void Initialize()
{
this.CurrentClass.FirstCoefficient = 0;
this.CurrentClass.SecondCoefficient = 5;
this.Initialized = true;
}
}
Call Initialize() method where your conditions met.
Later in code you can just check if(currentObject.Initialized). Notice private setter for `Initialized' property, it will ensure this flag was not accidentally set by external code.
Depending on your needs, you can go further and pass parameters for initialization directly to Initialize() method as parameters.
You have several approaches, like force values to be correct in constructor or have another variable telling if object has no value yet, like System.Drawing.Point has static "Empty" property. But in this case of your simple object your main class is explicitly creating an instance of CurrentClass so at this point this object should be correct and coefficients should be set. If you rely on some other code to set those values to perform some other action later, it is out of scope of these two objects here.
Update: perharps sharing details of what the real problem is would be better, because I have a feeling trying to provide a simpified example ended up in hiding real problem.
I am pretty new to OOP and looking into things in a bit more depth, but I have a bit of confusion between these 3 methods in C# and which one is best and what the differences are between 2 of them.
Example 1
So lets start with this one, which (so I understand) is the wrong way to do it:
public class MyClass
{
public string myAttribute;
}
and in this way I can set the attribute directly using:
myObject.myAttribute = "something";
Example 2
The next way I have seen and that seems to be recomended is this:
public class MyClass
{
public string myAttribute { get; set;}
}
With getters and setters, this where I dont understand the difference between the first 2 as the variable can still be set directly on the object?
Example 3
The third way, and the way that I understand the theory behind, is creating a set function
public class MyClass
{
string myAttribute;
public void setAttribute(string newSetting)
{
myAttribute = newSetting;
//obviously you can apply some logic in here to remove unwanted characters or validate etc.
}
}
So, what are the differences between the three? I assume example 1 is a big no-no so which is best out of 2 and 3, and why use one over the other?
Thanks
The second
public class MyClass
{
public string MyAttribute { get; set;}
}
is basically shorthand for:
public class MyClass
{
private string myPrivateAttribute;
public string MyAttribute
{
get {return myPrivateAttribute;}
set {myPrivateAttribute = value;}
}
}
That is an auto-implemented property, which is exactly the same as any regular property, you just do not have to implement it, when the compiler can do that for you.
So, what is a property? It's nothing more than a couple of methods, coupled with a name. I could do:
public class MyClass
{
private string myPrivateAttribute;
public string GetMyAttribute()
{
return myPrivateAttribute;
}
public void SetMyAttribute(string value)
{
myPrivateAttribute = value;
}
}
but then instead of writing
myClass.MyAttribute = "something";
string variable = myClass.MyAttribute;
I would have to use the more verbose, but not necessarily clearer form:
myClass.SetMyAttribute("something");
string variable = myClass.GetMyAttribute();
Note that nothing constraints the contents of the get and set methods (accessors in C# terminology), they are methods, just like any other. You can add as much or as little logic as you need inside them. I.e. it is useful to make a prototype with auto-implemented properties, and later to add any necessary logic (e.g. log property access, or add lazy initalization) with an explicit implementation.
What your asking here has to do with encapsulation in OOP languages.
The difference between them is in the way you can access the propriety of an object after you created an object from your class.
In the fist example you can access it directly new MyClass().MyAttribute whether you get or set it's value.
In the second example you declare 2 basic functions for accessing it:
public string MyAttribute
{
get {return myPrivateAttribute;}
set {myPrivateAttribute = value;}
}
In the third example you declare your own method for setting the value. This is useful if you want to customize the setter. For example you don't want to set the value passed, but the value multiplied by 2 or something else...
I recommend some reading. You can find something here and here.
Property is a syntactic sugar over private attribute with get and set methods and it's realy helpful and fast to type;
You may treat automatic property with { get; set;} as a public attribute. It has no additional logic but you may add it later without uset ever notice it.
Just exchange
public string MyLine { get; set;}
to
string myLine;
public string MyLine
{
get { return myLine; }
set { myLine = value + Environment.NewLine; }
}
for example if you need so.
You can also easily create read only property as { get; private set }.
So use Properties instead of public attributes every time just because its easier and faster to write and it's provides better encapsulation because user should not be used get and set methods if you decide to use it in new version of yours programm.
One of the main principles of OOP is encapsulation, and this is essentially the difference between the first example and the other 2.
The first example you have a private field which is exposed directly from the object - this is bad because you are allowing mutation of internal data from outside the object and therefore have no control over it.
The other 2 examples are syntactically equivalent, the second being recommended simply because it's less code to write. However, more importantly they both restrict access & control mutation of the internal data so give you complete control over how the data should be managed - this is ecapsulation.
In my project I have one class called Area like below.
The property "CodArea" I want to put one custom attribute like [NaoSelecionarAttr(true)].
This is working fine but when I create one instance of the class I can not get this custom attribute. Something like this:
Area areaPoco = new Area();
areaPoco.CodArea.GetType().GetCustomAttributes(typeof(NaoSelecionarAttr),true).ToList();
[Serializable]
public class Area
{
#region Private Members
private decimal _numChave;
private string _codArea;
public Area()
{
_numChave = 0;
_codArea = null;
}
public Area(decimal pNumChave, string pCodArea)
{
NumChave = pNumChave;
CodArea = pCodArea;
}
public virtual decimal NumChave
{ get { return _numChave;}
set { _numChave = value;}
}
[NaoSelecionarAttr(true)]
public virtual string CodArea
{
get { return _codArea; }
set { _codArea = value;}
}
}
public class NaoSelecionarAttr : Attribute
{
public bool NaoSelecionar { get; set; }
public NaoSelecionarAttr(bool pSim) { this.NaoSelecionar = pSim; }
}
}
There are some problems with your code.
The first problem in the code is that you are calling the default constructor on Area, which initializes _codArea to null. And then you try to call GetType on it, which fails with a NullReferenceException, as expected.
The second problem is that you want an attribute of a property of a class. So you must inspect (or reflect) the class, not the property. You see, when you write areaPoco.CodArea... the compiler resolves it to the result of your get expression, in this case, the field _codArea. By calling GetType() on _codArea, what you retrieve is a String type, not your Area type. I know this may seem confusing at first, but properties aren't types, so you can't reflect on them.
What you should do, then, is:
Area areaPoco = new Area();
NaoSelecionarAttr attr = (NaoSelecionarAttr) (areaPoco.GetType().GetProperties().Single(p => p.Name == "CodArea").GetCustomAttributes(typeof(NaoSelecionarAttr), true).Single());
bool naoSelecionar = attr.NaoSelecionar;
If I may, I want to give you some tips as well:
Your notation for the non-default constructor seems reminiscent of C/C++. There usually isn't a good reason to stick a "p" prefix in the parameters.
Instead of NaoSelecionar, which is a negative property, I recommend you work with "Selecionar". The deal is that you can easily confuse a negative sentence with its correspondent positive one. A month from now you will ask, "ok, the parameter is false, so should I select or not this property?". False usually means NOT, so, your default interpretation would be not to select something when the property is false.
Your default constructor is initializing a property to null. Just as I described above, this can result in bugs. Either initialize it to a default value (string.Empty), or remove the default constructor and use only the one that requires the user to provide a value to string. And validate those parameters as well -- the user might provide again a null to the string. (An object should be valid when first constructed)
One final tip. Your NaoSelecionar attribute gets a boolean parameter. The last bullet was exactly about that -- you can confuse whether having a true property for your attribute means "não" or "sim". Well, why don't you simply remove the parameter and then work with a negative parameter? There's no need to pass true or false to NaoSelecionar, since all you need to do is iterate through your class and find which properties have this attribute applied to them.
Why do you use areaPoco.CodArea.GetType()? I think you should use areaPoco.GetType(). Because your custom attribute belongs to the Area class, not to the string.