Passing object attribute to method parameter C# - c#

Lets say I have a person class with name and id and a animal class with the same attributes, and i have a list with persons and animals. Now i want to make a method for returning the last id from that list and increment it. I want to make it universal so i can use it later.
public static int getNextId(List<Object>param)
{
int lastId = Int32.Parse(param[param.Count - 1].id);
if (lastId!=0)
{
return lastId++;
}
return 0;
}
but the 'id' is underlined because object does not have id.
Edit:
something like this in python
def someMethod(self, someList, attr):
objAttr = getattr(someObject, attr)
for(item in someList):
return item.objAttr

Your approach is not how you handle stuff like this in statically typed languages such as C#. You can only access properties / fields that are declared on the specific type. And object does not have a public field or property called id.
There are some ways around this: One would be having a base class that has an id property from which your other classes could inherit:
public class IdHolder
{
public int Id { get; set; }
}
public class Person : IdHolder
{
// Person inherits the 'Id' property from IdHolder
// other properties unique to person...
}
IdHolder could just as well be an interface or an abstract class - it depends on your specific use case (note that you would have to implement the Id property in each implementing class if you'd chose to make IdHolder an interface).
If you chose to have a base class (or interface, ...) you'd change your method to accept that as a parameter:
public static int getNextId(List<IdHolder>param)
{
int lastId = param[param.Count - 1].Id;
if (lastId!=0)
{
return lastId++;
}
return 0;
}
Another - slightly dirty - option is to use reflection. As I don't think that this is a sensible route for you to take, I won't go further into this here.
I'd advise you to have a look at an intro book into C# as there are some other aspects of your code that don't really follow C# guidelines (e. g. using camelCase instead of PascalCase).

Create a Person class with a Id Property like this:
public class Person
{
public int Id {get; set;}
}
So you can use:
public static int getNextId(List<Person>param)
{
int lastId = param.Last().Id;
if (lastId!=0)
{
return lastId++;
}
return 0;
}
Another aproach is using interfaces to make "universal" like you said:
public interface IId
{
int Id {get;set;}
}
public class Person : IId
{
public int Id {get; set;}
}
public static int getNextId(List<IId>param)
{
int lastId = param.Last().Id;
if (lastId!=0)
{
return lastId++;
}
return 0;
}

public static int GetNextId(List<object> param)
{
int id = param.OfType<Person>().Last().Id;
return ++id;
}
OfType method filters the elements based on a specified type. Only people will be filtered from the list of people and animals.
Last method returns a last element of a sequence.

Related

How to instantiate a class that has a Generic List and initialize the list at runtime without using dynamic or Reflection

Given classes that are like these, is there a way to instantiate the Employee class and initialize the Generic List at runtime. Company rules preclude me from using dynamic, and using Reflection is frowned upon, but if there is no other way I can use it.
class Employee
{
public void SetList<T>(List<T> list) where T : IInputRow<T>
{
InputRows = list;
}
public List<T> InputRows;
public string EmployeeName {get; set;}
}
interface IInputRow<T>
{
T Parse(DataRow dr);
}
class JobRow : IInputRow<JobRow>
{
public int RowID {get; set;}
public string RowName {get; set;}
public JobRow Parse(DataRow dr)
{
//logic to convert datarow to entity
}
}
class VolunteerRow : IInputRow<VolunteerRow>
{
public int VolunteerRowID {get; set;}
public int VolunteerHours {get; set;}
public VolunteerRow Parse(DataRow dr)
{
//logic to convert datarow to entity
}
}
The list type has to be decided at run time.
I appreciate the comments and the answer, however, given that there are 46 different types of input rows I do not want to make the employee class generic as that would result in have to instantiate it for each input row that is needed for that round of processing. I might end up using reflection but I am somewhat hesitant about that given the sheer number of records that could conceivably be processed during a single run.
Try this Employee class:
public class Employee<T> where T : IInputRow<T>
{
public List<T> list;
public Employee()
{
list = new List<T>();
}
}
The <T> after class name is the magic. When you want a new Employee class with a List<JobRow>, you say Employee<JobRow> j = new Employee<JobRow>();.
Refer to Microsoft generic document for more info: https://learn.microsoft.com/en-us/dotnet/standard/generics/

Conditional instantiation of class in nested classes

Below is an example of what I am trying to do.
public class Map{
int id;
int type;
List<Points>;
}
public class Points{
int xpos;
int ypos;
int id;
//Building bg; or Parking pg;
}
public Building{}
public Parking{}
Now according to the type attribute in Map class I need to add either Building or Parking class object into Points Class.
Eg: If type == 1 then add Building to Points else if type == 2 add Parking to Points.
Could anyone please help me with this ?
A way to do it, is to make both Building and Parking inherit from Point (I'd recommend a better name by the way, maybe Location).
public class Location
{
public int Id { get; }
public int X { get; }
public int Y { get; }
}
public class Building : Location
{
public int Stories { get; }
}
public class Parking: Location
{
public int Capacity { get; }
}
And now, your List<Location> inside Map can handle both buildings and parkings:
locations.Add(someBuilding);
locations.Add(someParking);
Another option is to use interfaces: interface ILocation that will be implemented by Building and Parking and a List<ILocation> in Map.
When to use one or another depends on what the commonality between the different types really is:
Inheritance: A derived type is a base class, A dog is an animal.
Interfaces: A type implementing an interface behaves like the interface. An int behaves like an IEquatable<int>, a string too. Is there anything in common between string and int besides this behavior?

C# access children's static member in parent

I have a class Foo, which is a base class for a lot other classes such as Bar and Baz, and I want to do some calculation within Foo using the static members in Bar and Baz, as shown below:
public class Foo{
public result1 {
get{
return field1;
}
}
}
public class Bar : Foo{
public const int field1 = 5;
}
public class Baz : Foo{
public const int field1 = 10;
}
The only solution I can think of is wrap all the fields in a container, add an extra identifier for each object, and use a function to return the fields, like so
Bar : Foo{
public readonly int id = 0;
public static Wrapper wrapper;
}
public Wrapper GetWrapper(int id){
switch(id){
case 0:
return Bar.wrapper;
}
}
However, as you can see, I need to maintain one additional class and function, and I'd rather not to fragment my code. Is there any alternative?
Edit
What you are asking for, i.e. accessing a static or const value in a subclass from a base class is technically possible, but doing so will violate the principals of good SOLID OO design. Also, since you will need an instance of a specific subclass in order to be able to 'reason over' the type of the subclass in order to obtain the appropriate field1, there's little point approaching this problem statically.
Instead, the common, cleaner, approach here is to use subtype polymorphicism which will allow a calling method in the base class, or a method in an external class altogether, to access the appropriate value for 'field1' based on the subclass. This allows control over the value returned to remain inside the appropriate subclasses (i.e. as per your words, the code won't become "fragmented").
Alternative solution using subclass polymorphicism (recommended)
A subclass polymorphic approach (i.e. with the virtual/abstract and override keywords) will allow you to encapsulate the retrieval of a value (or object) which is customizable for each subclass. Here, the abstraction remains conceptually at "give me an integer value", and then the sub-class-specific implementations of 'how' to return the value can be abstracted (hidden) from the caller. Also, by marking the base property as abstract, you will force all subclasses to implement the property, so that the requirement to provide a value isn't forgotten about.
i.e. I would recommend a polymorphic approach like this:
public abstract class Foo
{
public abstract int Result { get; }
}
public class Bar : Foo
{
// This is implementation specific. Hide it.
private const int field1 = 5;
public override int Result
{
get { return field1; }
}
}
public class Baz : Foo
{
public override int Result
{
// No need for this implementation to be a constant ...
get { return TheResultOfAReallyComplexCalculationHere(); }
}
}
If there are no other reusable concrete methods on the base class Foo, then you could also model the abstraction as an interface, with the same effect:
public interface IFoo
{
int Result { get; }
}
Approaching this problem without polymorphicism (Not recommended)
Any compile-time attempt to access static fields on subclasses will typically require code somewhere to switch (or map) on the actually type of the subclass instance, e.g.:
public class Foo
{
public int result1
{
get
{
switch(this.GetType().Name)
{
case "Bar":
return Bar.field1;
case "Baz":
return Baz.field1;
default:
return 0;
}
}
}
public void MethodRequiringValueFromSubclass()
{
Console.WriteLine(result1);
}
}
public class Bar : Foo
{
public const int field1 = 5;
}
public class Baz : Foo
{
public const int field1 = 10;
}
The problem here is that the Open and Closed principal is violated, as each time a new sub class is added, the result1 method would need to be changed to accomodate the new class.
I'd suggest to use abstract function rather that using static member.
public abstract class Foo{
public result1 {
get{
return get_field1();
}
}
protected abstract int get_field1();
}
public class Bar : Foo{
public const int field1 = 5;
protected override int get_field1() { return field1;}
}
public class Baz : Foo{
public const int field1 = 10;
protected override int get_field1() { return field1;}
}
You either add constructor parameter to your Foo class which can be passed from inheritors, thus you don't need extra classes also you'll have less coupling
public class Foo
{
private readonly int _field1;
public Foo(int field1)
{
_field1 = field1;
}
}
or you can use it exactly from inheritors type as static/const members are members of class type
public class Foo
{
public result1
{
get
{
return Bar.field1;
}
}
}
but this gives your code less flexibility and more coupling.
Also you have an option by using virtual properties which you can implement in derrived classes and use in base:
public class Foo
{
public virtual int Field { get { return 0; } }
}
Instead of making Foo abstract as other answers suggested you can use virtual and override result1 in each child class
public class Foo
{
public virtual int result1 { get; }
}
public class Bar : Foo
{
public const int field1 = 5;
public override int result1
{
get { return field1; }
}
}
public class Baz : Foo
{
public const int field1 = 10;
public override int result1
{
get { return field1; }
}
}
If you want default result1 to return something else than 0 you can give it another value
public class Foo
{
public virtual int result1 { get; } = -1;
}
I always feel like a jerk when I answer my own question... Yet didn't see what I was expecting so I might as well just share what I've got after a night of mind boggling.
The reason I don't want to make the calculation abstract/virtual is because there are many subclasses and the formula is the same for all of them. I just refuse to type the same code 10-20 times repeatedly.
Couldn't make the static fields non static either, as they should be accessible at a class level plus they can get big, and they are the same for all instances.
The only solution I can come up that minimizes code fragment is something like this
public class Foo {
public class Wrapper {
Fields...
}
public Wrapper wrapper; // reference
public int result1 { get; }
}
public class Bar : Foo {
public static Wrapper subclassWrapper; // put in the implementation
public Bar() : base(){
wrapper = subclassWrapper;
}
}
So each instance now needs to hold an extra reference, however I don't need to keep a function. The wrapper is kept within the base class so it is less fragmented.

Can C# constraints be used without a base type?

I have some classes with common properties, however, I cannot make them derive from a base type (LINQ-to-SQL limitations).
I would like to treat them as if they had a base type, but not by using Reflection (performance is critical).
For example:
public class User
{
public int Id { get; set; }
public string FirstName { get; set; }
}
public class Vehicle
{
public int Id { get; set; }
public string Label { get; set; }
}
In this case I would be happy if I had the Id property available, regardless of the type I'm holding.
Is there any way in C# to to something similar to this:
public static int GetId<T>(T entity) where T // has an int property 'Id'
{
return entity.Id;
}
I guess I could have used dynamic, however, I'm looking for a way to restrict the code in compile time from using this method for an object that has no Id property.
You can use interfaces:
public interface IHasId
{
int Id { get; }
}
public class User : IHasId { ... }
public class Vehicle : IHasId { ... }
public static int GetId<T>(T entity) where T : IHasId
{
return entity.Id;
}
However, if you are not able to modify the classes to add the interface, you won't be able to do this. No compile-time checks will verify that a property exists on T. You'd have to use reflection - which is slow and obviously not ideal.
There is no way to guarantee a type has a given member without constraining to a common base type or interface. One way to work around this limitation is to use a lambda to access the value
public static int Use<T>(T value, Func<T, int> getIdFunc) {
int id = getIdFunc(value);
...
}
Use(new User(), u => u.Id);
Use(new Vehicle(), v => v.Id);
You can create an interface with the common properties and make your classes implement it:
public interface IEntity
{
int Id { get; set; }
}
public class User : IEntity
{
public int Id { get; set; }
public string FirstName { get; set; }
}
public class Vehicle : IEntity
{
public int Id { get; set; }
public string Label { get; set; }
}
public static int GetId<T>(T entity) where T : IEntity
{
return entity.Id;
}
You could simplify GetId like this:
public static int GetId(IEntity entity)
{
return entity.Id;
}
The other answers mentioning the interface approach are certainly good, but I want to tailor the response to your situation involving Linq-to-SQL.
But first, to address the question title as asked
Can C# constraints be used without a base type?
Generally, the answer is no. Specifically, you can use struct, class, or new() as constraints, and those are not technically base types, and they do give some guidance on how the type can be used. That doesn't quite rise to the level of what you wish to do, which is to limit a method to types that have a certain property. For that, you will need to constrain to a specific interface or base class.
For your specific use case, you mention Linq-to-SQL. If you are working from models that are generated for you, then you should have options to modify those classes without modifying the generated model class files directly.
You probably have something like
// code generated by tool
// Customer.cs
public partial class Customer // : EntityBaseClasses, interfaces, etc
{
public int ID
{
get { /* implementation */ }
set { /* implementation */ }
}
}
And other similar files for things such as Accounts or Orders or things of that nature. If you are writing code that wishes to take advantage of the commonly available ID property, you can take utilize the partial in the partial class to define a second class file to introduce a common interface type to these models.
public interface IIdentifiableEntity
{
int ID { get; }
}
And the beauty here is that using it is easy, because the implementation already exists in your generated models. You just have to declare it, and you can declare it in another file.
public partial class Customer : IIdentifiableEntity { }
public partial class Account : IIdentifiableEntity { }
// etc.
This approach has proven valuable for me when using a repository pattern, and wishing to define a general GetById method without having to repeat the same boilerplate in repository after repository. I can constrain the method/class to the interface, and get GetById for "free."
Either you need to make both classes implement an interface with the properties you need, and use that in the generic constraint, or you write separate methods for each type. That's the only way you'll get compile-time safety.

How to inherit a static property with a unique value for each subclass?

I have a series of objects, lets call them buildings, that each share certain properties that are static for that building, but different for each building, such as price. I assumed that the best way to implement this was to create an abstract superclass with the shared price attribute and set the values in each subclass, but I cannot figure out how to get this to work. Here is an example of something I have tried:
using System;
public abstract class Buildings
{
internal static int price;
internal static int turnsToMake;
}
using System;
public class Walls : Buildings
{
public Walls()
{
price = 200;
turnsToMake = 5;
}
}
This works fine for construction, but if I want to check the price before creating it (to check if the player has enough money) then it just returns a null value. I'm sure that it is is a super simple fix, but I can't figure it out. Any help?
There is a "patchy" yet simple solution that's worth to consider. If you define your base class as a Generic class, and in deriving classes set T as the class itself, It will work.
This happens because .NET statically defines a new type for each new definition.
For example:
class Base<T>
{
public static int Counter { get; set; }
public Base()
{
}
}
class DerivedA : Base<DerivedA>
{
public DerivedA()
{
}
}
class DerivedB : Base<DerivedB>
{
public DerivedB()
{
}
}
class Program
{
static void Main(string[] args)
{
DerivedA.Counter = 4;
DerivedB.Counter = 7;
Console.WriteLine(DerivedA.Counter.ToString()); // Prints 4
Console.WriteLine(DerivedB.Counter.ToString()); // Prints 7
Console.ReadLine();
}
}
Don't use static. Static says that all instances of Building have the same value. A derived class will not inherit its own copy of the statics; but would always modify the base class statics. In your design there would only be one value for price and turnsToMake.
This should work for you:
public abstract class Buildings
{
internal int price;
internal int turnsToMake;
}
However, most people don't like using fields these days and prefer properties.
public abstract class Buildings
{
internal int Price { get; set; }
internal int TurnsToMake { get; set; }
}
I want to check the price before creating it […]
I suppose that's how you got to static fields; however, static and virtual behaviour cannot be combined. That is, you would have to re-declare your static fields for each subclass. Otherwise, all your subclasses share the exact same fields and overwrite each others' values.
Another solution would be to use the Lazy<T, TMetadata> type from the .NET (4 or higher) framework class library:
public class Cost
{
public int Price { get; set; }
public int TurnsToMake { get; set; }
}
var lazyBuildings = new Lazy<Buildings, Cost>(
valueFactory: () => new Walls(),
metadata: new Cost { Price = 200, TurnsToMake = 5 });
if (lazyBuildings.Metadata.Price < …)
{
var buildings = lazyBuildings.Value;
}
That is, the metadata (.Metadata) now resides outside of the actual types (Buildings, Walls) and can be used to decide whether you actually want to build an instance ( .Value) of it.
(Thanks to polymorphism, you can have a whole collection of such "lazy factories" and find a building type to instantiate based on the metadata of each factory.)
Building on Uri Abramson's answer above:
If you need to access the static property from within the Base class, use reflection to get the value from T. Also, you can enforce that Base must be inherited using T of the derived type.
e.g.
class Base<T> where T : Base <T> {
static int GetPropertyValueFromDerivedClass<PropertyType>(BindingFlags Flags = BindingFlags.Public | BindingFlags.Static, [CallerMemberName] string PropertyName = "")
{
return typeof(T).GetProperty(PropertyName, Flags)?.GetValue(null);
}
static int Counter{ get => GetPropertyValueFromDerivedClass(); }
}
static int DoubleCounter{ return Counter*2; } //returns 8 for DerivedA and 14 for DerivedB
}
If you have a better way to do this, please post.
Not as easy for the inheritor, but workable...
public abstract class BaseType
{
public abstract contentType Data { get; set; }
}
public class InheritedType : BaseType
{
protected static contentType _inheritedTypeContent;
public override contentType Data { get => _inheritedTypeContent; set => _inheritedTypeContent = value; }
}

Categories

Resources