Why does Equals method of attributes compare fields? [closed] - c#

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 1 year ago.
Improve this question
When I checked the attributes for equality, I noticed that they already have Equals method that compares the fields. For custom classes this comparison does not occur, since it is bad for performance, but why was an exception made for attributes?
Here's the code to make sure:
public class MyAttribute : Attribute
{
public int Value { get; }
public MyAttribute(int value) => Value = value;
}
public class MyClass
{
public int Value { get; }
public MyClass(int value) => Value = value;
}
public class Test
{
[Test]
public void TestEquals()
{
var myAttributeLeft = new MyAttribute(1);
var myAttributeRight = new MyAttribute(1);
var attributeEqualityResult = myAttributeLeft.Equals(myAttributeRight);
Console.WriteLine(attributeEqualityResult); // true
var myClassLeft = new MyClass(1);
var myClassRight = new MyClass(1);
var classEqualityResult = myClassLeft.Equals(myClassRight);
Console.WriteLine(classEqualityResult); // false
}
}

Custom attributes are not intended for use as domain objects: they are explicitly intended to represent metadata that are hard-coded at compile time. Assuming they are used as intended, this gives them a few special properties:
There are limits on the types that they are allowed to use: typically native types like int and string, and arrays of those native types.
The number of items that could be put into an array on the type is bounded by the number of items that are written into an actual code file.
In domain models it could create enormous performance penalties to compare the values of fields, properties, and elements of collections: you don't know how big the object structure for a given class might be, and a collection could have millions of items in it. But the restrictions mentioned above mean that the cost of an equality comparison for custom attributes is pretty well bounded. Evidently the creators of .NET felt that this made it worthwhile to give the base class value semantics, although the documentation includes remarks that recommend overriding the default implementation to use object equality or hard-coded value semantics instead.

Short answer: System.Attribute implements its own implementation of Equals which is different from the one in System.Object (from which MyClass class inherits)
You can find a more detailed answer on ms docs

Related

C# What is the best way to split one large class to multiple, so variables would be shared between them [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 1 year ago.
Improve this question
I am trying to find a way to use a group of classes that will share methods and variables.
I want to make a class or classes that will work with data, in the format similar to csv file.
I created a large class named "Data", it is supposed to hold main variables with, well, data.
However, from what I am learning online, it's best that one class deals with just one aspect of program.
So, the Data class will have actual variables, like the text, columns and the like, and a usual constructor.
internal class Data
{
private readonly int _id;
protected DateTime LastUpdateTime;
protected readonly List<Column> Columns = new List<Column>();
protected List<string> DataText = new List<string>();
protected string Headers;
public Data()
{
_id = Global.Last();
LastUpdateTime = DateTime.Now;
}
public Data(List<string> dataText, char separator, Boolean hasHeaders) : base()
{
DataText = dataText;
//DataManageColumns dataManageColumns = new DataManageColumns();
new DataManageColumns().CreateColumns();
new DataManageSeparator().Separator = separator;
if (hasHeaders == true)
{
new DataManageHeaders().SetHeaders();
new DataManageHeaders().ExcludeHeadersFromDataText();
}
}
public int GetId()
{
return _id;
}
}
But, I do want to make every aspect of work, like getting an actual text, or counting the number of columns, or saving the time when there was a last change, or whatever be in its own class.
Example:
class DataManageColumns : Data
{
public void CreateColumns()
{
for (int i = 0; i < DataText.Count; i++)
{
string[] splitLine = DataText[i].Split(Global.CurrentData().DataManageSeparator.Separator);
if (i == 0)
{
for (int j = 0; j < splitLine.Length; j++)
{
Columns.Add(new Column(j, splitLine[j]));
}
}
}
}
public List<Column> GetColumns()
{
return Columns;
}
public void SetColumns(List<Column> newColumns)
{
foreach (Column column in newColumns)
column.SetSerial(column.GetSerial());
}
}
It is inherited from the Data class, so it can use its variables.
But! How I can access DataManageColumns methods from the base Data class, or from any other class?
I did try adding it to Data like that:
internal DataManageColumns DataManageColumns = new DataManageColumns();
My original thought was to use something like:
specificData.dataManageColumns.DoWhatever();
While it didn't show an error, it crashed on running with Stack Overflow Exception.
I quickly understood why and will post it here to help others: new Data creates new ManageColumns, which calls for a new Data that again creates another ManageColumns and so infinitely.
The question is, how to solve this?
What I tried:
I tried using Nested classes, by the nested class can't use vars from main class (unless there is a way I don't know).
I considered making a partial class: but this will still be using one class for many aspects, which is against SOLID principles.
I tried making sub-classes static, but using static makes it impossible to inherit or be inherited.
I believe I am not the first who wants to do something like that, and it isn't supposed to be that hard to implement. But I can't find a way to do it.
Can you please help?
Thank you,
Evgenie
UPD: I highly prefer, if it's possible, to access methods from sub-classes from using Data.
Like if using data object of Data class:
data.MethodFromSubClass();
But! How I can access DataManageColumns methods from the base Data
class, or from any other class?
You don't. Prefer composition to inheritance (Composition v Inheritance), since a DataManageColumns class isn't a specific type of Data class (in the way a triangle is a type of shape). The former makes use of the latter and furthermore the Data class shouldn't need to know anything about DataManageColumns or any other class that makes use of it.

Trying to understand indexers in C# [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
I am trying to understand indexers in C#. In the accepted answer, I am not able to understand how:
public float this[int index]
{
get{
return temps[index];
}
set{
temps[index] = value;
}
}
works. As in what if I have 2 float variables?
To put it simply, Idexers is a technique that you can use to allow a class to behave in a similar way to an array, by allowing you can access values by using an index.
generally you would only do this if conceptually the class is supposed to behave like an array, its primary function is to hold a single collection of other objects.
A common scenario is when the class is a wrapper for an internal array variable that you do not want to directly expose. We try to avoid classes inheriting from arrays or IEnumerable because there is a lot of functionality to implement, but wrapping an array for the purposes of adding additional functionality can make a lot of sense.
temps in your syntax public float temps this[int index] doesn't make sense, and is not necessary because a class can only have a single indexer of each type.
Instead of using an indexer, if the temps field was exposed as public, then you could use this syntax instead to access the value for the index of 5:
TempratureRecord oTest = new TemperatureRecord();
var tempAtIndex5 = oTest.temps[5];
But now you have access to the temps variable itself, meaning you could reassign it altogther.
Do not mistake that example as the only way to expose values from internal arrays, if you had multiple arrays then you can expose them in different ways, generally NOT by using an indexer.
If the indexer only exposes an internal array, but offers nothing more, then that's probably not a great reason to use them at all.
You can have an indexer of say type string and a separate indexer of type int, this is a common pattern if the internal array is an array of objects that might have both a unique string and int property that can be used to identify the correct object to return.
However you would not generally do this just because you have an array of ints and an array of strings. The general expectation of Indexers is that if there are multiple indexers, we are offering the caller a different way to access the same conceptual list of objects, and indeed to target the same object in different ways, perhaps because we do not know the index of that object in the internal array.
An example of how multiple indexers might be used to access the same internal array, but showing how the index passing in doesn't have to be the index at all that is used internally:
Note: by doing it this way, it may not make sense to allow a setter at all
public class Person
{
string Name { get; set; }
int Id { get; set; }
}
public class People
{
private Person[] _backingStore;
/// <summary>Instantiate a new list of people</summary>
public People(params Person[] persons)
{
_backingStore = persons;
}
/// <summary> Return a person from this list by Id </summary>
public Person this[int id]
{
get{
return _backingStore.Where(p => p.Id == id).FirstOrDefault();
}
}
/// <summary> Return a person from this list by Name </summary>
public Person this[string name]
{
get{
return _backingStore.Where(p => p.Name == name).FirstOrDefault();
}
}
}
...
People list = new People(
new Person(){ Id = 26, Name = "Hassan" },
new Person(){ Id = 101, Name = "John Skeet" }
);
var john = list["John Skeet"];
var alsoJohn = list[101];
var no1 = list["someone else"];
var hassan = list["Hassan"];

Access C# anonymous type object returned from a method [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
Someone wrote a method that returns an object type.
public object GetProvider(double personId)
{
// Some other code here
return new {
FirstName = Convert.ToString(reader["FirstName"]),
LastName = Convert.ToString(reader["LastName"])
};
}
In different part of code, we use this library method.
var d = GetProvider(123);
string fName = d.GetType().GetProperty("FirstName").GetValue(d, null).ToString();
How can I improve this code or simplify it? I guess they should have created a class and returned an object of it instead of object type. Also, I have seen code that use dynamic in C#4. I tried that, but it didn't work well with object type. Any thoughts?
Implement dynamic like this:
dynamic d = GetProvider(123);
string fName = d.FirstName;
It seems that this part is actually irrelevant to the original post, as the OP has no control over the method's return-type. I'm leaving it here because it's still best-practice and should be followed in a significant majority of cases, and in an ideal world, the writer of the original method would read this and change his or her ways.
But in general, I'd be tempted to just make a type. It's not like it takes all that much effort to spin up a class to do exactly what you want.
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
Then you can have everything strong-typed and you don't need to use dynamic. I don't think I've ever found a truly appropriate use for dynamic. It's nice because it's quick and easy to write, but it tends to just cause problems in the long run in 99% of real-world uses. I'm not saying it should be abolished because that 1% is useful (I'm thinking serialization of dynamic data here, but even there I usually just use the string indexer properties), but generally speaking, think twice before using it and make sure there isn't a better solution. Anonymous types are useful in LINQ queries where it's all in-scope and compiled, but I wouldn't change scopes using them unless you absolutely have to, and you pretty well never do.
If this were me, I would probably wrap the result from GetProvider in a strongly typed class. The class below takes the response from GetProvider as an argument on its constructor.
public class Provider
{
public Provider(object provider)
{
dynamic dynamicProvider = provider;
this.FirstName = dynamicProvider.FirstName;
this.LastName = dynamicProvider.LastName;
}
public string FirstName { get; set; }
public string LastName { get; set; }
}
Then just replace
var d = GetProvider(123);
with
var d = new Provider(GetProvider(123));

Creating data members of a class in C# [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
I am a beginner programmer looking for some help with c#.
I am writing a program based on a framework and need to create a data member of a class, then initialize the data member to something.
Next,I need to make a property to get and set the data member.
Also, if someone could provide some information on how to typecast the property that would be great.
I'm just looking for examples and general information here. I checked google and only got links from MSDN but did not understand the content.
Thanks!
Here is a basic explanation, using code:
//Class Definition
public class MyClass
{
//Data Member with inline initialization
private int myInt = 1;
//Standard property
public int MyIntProp
{
get { return myInt; }
set { myInt = value; }
}
//Auto-property, generates the same getter/setter as above with a "hidden" backing property.
public String MyStringProp {get; set;}
//Class constructor, great for initialization!
public MyClass()
{
//Set the property to an initial value
MyStringProp = "Hello World";
}
}
Typecasting is another monster. You have to be careful when doing it, because very few types can be cast to others. The number types can generally be cast to one another (although you can lose data), and derived types can be cast to their base types, but that is about it.
An example (safe) cast of a number would be:
int myInt = 2;
long myLong = (long)myInt;
That is called a "C-Style" cast (because it's how you do it in C) and is generally how you cast numbers. There are other styles and functions to do the cast of course.
#Iahsrah's suggestion is also a good place to start.
A basic type is a class which looks like this:
public class MyType
{
}
You can create a property of this on another class like this:
public class AnotherType
{
public MyType InlinePropertyName { get; set; }
// Simple propertoes require no implimentation (above), or you can explicitly control it all (below)
private MyType _explicitPropertyName;
public MyType ExplicitPropertyName {
get {
return _explicitPropertyName;
}
set {
_explicitPropertyName = value;
}
}
}
The you can easily access from elsewhere in your program like this:
var myType = new MyType();
var anotherType = new AnotherType();
anotherType.InlinePropertyName = myType;

difference between constructor and properties in C# [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I am new to programming, could someone please explain me difference between constructor and property in context to C#.
since both used to initialized your class fields, & also which one to choose in a given situation .
Besides all the technical stuff, a good rule of thumb is to use constructor parameters for mandatory things, properties for optional things.
You can ignore properties (hence optional), but you can't ignore constructor parameters (hence mandatory).
For everything else, I'd recommend reading a C# beginners book or tutorial ;-)
A property is just a class member that can be initialized when ever.
Like so:
var myClass = new MyClass();
myClass.PropertyA = "foo";
myClass.PropertyB = "bar";
A constructor is run when the class is created and can do various things. In your "scenario" it would probably be used to initialize members so that the class is in a valid state upon creation.
Like so:
var myClass = new MyClass("foo", "bar");
Constructor is a special type of method from the class to create the object itself. You should use it to initialize everything necessary to make the object work as expected.
From MSND Constructor:
When a class or struct is created, its constructor is called.
Constructors have the same name as the class or struct, and they
usually initialize the data members of the new object.
Properties enable a class to store, setting and expose values needed for the object. You should create to help in the behavior for the class.
From MSND Property:
A property is a member that provides a flexible mechanism to read,
write, or compute the value of a private field. Properties can be used
as if they are public data members, but they are actually special
methods called accessors. This enables data to be accessed easily and
still helps promote the safety and flexibility of methods.
Example:
public class Time
{
//
// { get; set; } Using this, the compiler will create automatically
// the body to get and set.
//
public int Hour { get; set; } // Propertie that defines hour
public int Minute { get; set; } // Propertie that defines minute
public int Second { get; set; } // Propertie that defines seconds
//
// Default Constructor from the class Time, Initialize
// each propertie with a default value
// Default constructors doesn't have any parameter
//
public Time()
{
Hour = 0;
Minute = 0;
Second = 0;
}
//
// Parametrized Constructor from the class Time, Initialize
// each propertie with given values
//
public Time(int hour, int Minute, int second)
{
Hour = hour;
Minute = minute;
Second = second;
}
}
Properties should be used to validate the values passed as well, for exemple:
public int Hour
{
//Return the value for hour
get
{
return _hour;
}
set
{
//Prevent the user to set the value less than 0
if(value > 0)
_hour = 0;
else
throw new Exception("Value shoud be greater than 0");
}
private int _hour;
Hopes this help you to understand! For more information about C# take a look at Object-Oriented Programming (C# and Visual Basic).

Categories