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?
Related
Lets say we have this example hierarchy:
abstract class Shape { }
class Circle : Shape
{
public int Radius { get; set; }
}
class Rectangle : Shape
{
public int A { get; set; }
public int B { get; set; }
}
I am wondering if it's possible to use pattern matching in C# on a variable of type Shape to determine if it has property Radius e.g.
// Imaginary syntax
if (myShape is { int Radius} )
{
}
I have not found that this is possible, so I assume the answer is no, but probably someone knows better.
Alternatives that I can think of:
Enumerate all the known scenarios (i.e. of Type Circle, etc.), downside is that an introduction of a new type in the future will break it
Introducing an interface, which might be cumbersome depending on the scenario
Using reflection (not too nice)
I have multiple classes that have a fled called "rows" however the rows field is of a different class type for each table.
So in the below example I have a fish table and a bird table. The table class is essentially the same but the rows field is of a specific class type making it easy for someone to reference properties on that object.
XXX.rows[0].canfly would be easy to reference if it's a bird.
So now I'm trying to write a generic method that can fetch multiple instances of FishTable or BirdTable .. do some magic, merge them into one table of that type and return the result. All the method needs to know is what type of table we're talking about and a few other basic parameters.
I know I'm approaching this incorrectly but I can quite tell where I'm falling down.
9 out of 10 times I run into something like this:
Severity Code Description Project File Line Suppression State
Error CS0311 The type 'GenericTest.FishTable<GenericTest.fish>' cannot be
used as type parameter 'T' in the generic type or method 'Tester.test<T>()'.
There is no implicit reference conversion from
'GenericTest.FishTable<GenericTest.fish>' to
'GenericTest.ITable<GenericTest.FishTable<GenericTest.fish>>'. GenericTest
C:\Users\WarrickF\source\repos\EOSTools\GenericTest\Program.cs 14 Active
I know I need to go an really understand Generics as I really no have business writing Generics like this without a descent understanding but .. well this is a real example I'm working through.
interface ITable<T>
{
List<T> rows { get; set; }
}
public class BirdTable<T> : ITable<T>
{
public List<T> rows { get; set; }
}
public class FishTable<T> : ITable<T>
{
public List<T> rows { get; set; }
}
public abstract class animal {
public int eyeCount;
}
public class bird : animal
{
public int featherCount;
public bool canFly;
}
public class fish : animal
{
public int numberOfFins;
public bool depth;
}
Chetan Ranpariya's comment is right on. I can try to help a bit anyway, but it's partly guesswork. You want to merge multiple tables, with rows of type T, but the error message seems to indicate that your code somewhere expects individual Ts instead.
There is no implicit reference conversion from
'GenericTest.FishTable<GenericTest.fish>' to
'GenericTest.ITable<GenericTest.FishTable<GenericTest.fish>>'.
There are rather more problems here, though. Your interface is working against you, and your class hierarchy is going to waste. So I'd suggest you simplify. First, I don't think you need a BirdTable<T> or FishTable<T>, because the T itself parameterizes the table type. You just need a TestTable<T> where T : animal.
Then in a method that merges them, you provide T and also where T : animal before the body's opening brace. Since they're parameterized by T, it's not possible to mix different table types.
I've taken the liberty of copying and then reworking what you did, below. I hope you find this helpful for getting insights into using generics. They do take some time to get used to. P.S., I've standardized your code to the usual naming conventions and encapsulation approaches in C#.
class Program
{
static string _animal;
static void Main(string[] args) {
TestTable<Bird> birds1 = new TestTable<Bird>();
birds1.Rows.Add(new Bird());
birds1.Rows.Add(new Bird());
TestTable<Bird> birds2 = new TestTable<Bird>();
birds2.Rows.Add(new Bird());
birds2.Rows.Add(new Bird());
TestTable<Bird> allBirds = MergeTestTables<Bird>(birds1, birds2);
int howManyBirds = allBirds.Rows.Count;
Console.WriteLine($"There are { howManyBirds } { _animal }s.");
Console.ReadKey(true);
}
public static TestTable<T> MergeTestTables<T>(params TestTable<T>[] tables) where T : Animal {
TestTable<T> merged = new TestTable<T>();
_animal = typeof(T).Name;
_animal = _animal.ToLower();
foreach (TestTable<T> table in tables) {
foreach (T row in table.Rows) {
merged.Rows.Add(row);
}
}
return merged;
}
public class TestTable<T> where T : Animal
{
public List<T> Rows { get; set; } = new List<T>();
}
public abstract class Animal
{
public int EyeCount { get; set; }
}
public class Bird : Animal
{
public int FeatherCount { get; set; }
public bool CanFly { get; set; }
}
public class Fish : Animal
{
public int NumberOfFins { get; set; }
public bool Depth { get; set; }
}
}
I created this interface:
public interface IPhrase
{
int CategoryId { get; set; }
string PhraseId { get; set; }
string English { get; set; }
string Romaji { get; set; }
string Kana { get; set; }
string Kanji { get; set; }
}
and this class:
public class Phrase : IPhrase
{
public Phrase()
{
}
public int CategoryId { get; set; }
public string PhraseId { get; set; }
public string English { get; set; }
public string Romaji { get; set; }
public string Kana { get; set; }
public string Kanji { get; set; }
}
Here this code returns data and typecasts it to Phrase:
var phrases = db2.Query<Phrase>("SELECT * FROM Phrase", ans);
var phrases = db2.Query<IPhrase>("SELECT * FROM Phrase", ans);
What I would like to know is if there is any difference / advantage in my using the IPhrase here or Phrase? Also what advantages are there (if any) in my creating a IPhrase interface in this example. Does that lead to more readable code?
An interface is a contract that guarantees, any class implementing the interface will implement the methods and properties defined in the interface. This allows you to use the interface to create methods, lists, etc. which accept any class that implements the interface e.g.
public interface IExample
{
int GetInt();
}
public void ProcessInt(IExample value)
{
var tempInt = value.GetInt();
// Do processing here
}
This allows any concrete class that implements interface IExample to be passed to this method. The method is assured that any concrete class passed will have the method GetInt implemented.
With objects you can inherit from to things:
Other Objects
Interfaces
Object
If you have an Animal object, a Dog object can inherit from it as it is an animal.
With Object inheritance think of the phrase: I am a ...._yourObject_...
Interface
With an interface you can think of it as a describer for that object. Such as IWalkOnTwoLegs or ICanSwim.
So think of the phrase : I can do ...._yourInterface_..
Now to answer your question, would it make a difference if you use an interface or not?
Well, it wouldn't in this case but if you extend your phrases and create a Question object and a Statement object, for example, and they inherit from Phrase, you have a choice where you can return all phrases (questions and statements) or only phrases that are Questions or only Statements.
You can also apply an interface saying IAmInFrench and IAmInSpanish to your phrase so you can have extended SpanishPhrase and FrenchPhrase objects.
Now you can return either all phrases whether they are questions, statements, in a different language, or you can be specific and return only french phases.
Where I find interfaces are most useful are for registration of different types in unity.
Where it will make a difference:
Where it will definitely make a difference is if there is a property on the object that isn't on the interface, then if you return the interface you will not be able to access that property very easily unless you type cast.
eg:
public class Phrase : IPhrase
{
public Phrase()
{
}
public int CategoryId { get; set; }
public string PhraseId { get; set; }
public string English { get; set; }
}
And interface
public interface IPhrase
{
int CategoryId { get; set; }
}
You will not be able to access the property English if you return the interface:
var phrases = db2.Query<IPhrase>("SELECT * FROM Phrase", ans);
var eng = phrases[0].English; //**THIS WONT WORK**
There is no difference between using an interface and a concrete object locally, as in your example. The main difference is when you are sending interfaces vs concrete classes as parameters in APIs or constructors parameters, where is preferably using interfaces so you can achieve decouple and testability.
Still for your question the short answer is no, there is no difference, whether you want to use interfaces or concrete objects as local variables is your own choice (what seems more readable to you). Do not forget that fields and properties are good to be declared as interfaces which provides more flexibility.
One last thing which should be considered when using a concrete object instead of an interface even locally is that you may want someday to change the signature of the method which provides you that object to return another kind of object which implements the same interface, and in that case you should change the local variable too (even if it's not so bad and it happens very rarely I had to note it), as in the following example:
interface IAnimal
{
void Run();
}
class Cat : IAnimal
{
public void Run()
{
//...
}
}
class Dog : IAnimal
{
public void Run()
{
//...
}
}
If in your code you have a method which returns a Cat that you use:
Cat GetAnimal()
{
return new Cat();
}
Cat myAnimal = GetAnimal(); //note that here it is expected a Cat
myAnimal.Run();
Then if you change the GetAnimal signature to return a Dog, your code should be changed in order to compile to:
Dog myAnimal = GetAnimal(); //note that here it is expected a Cat
myAnimal.Run();
But if you are using an interface there are less chances that your code will need to be changed when method's signatures ar changed:
IAnimal myAnimal = GetAnimal(); //this is working whether a Cat or a Dog is received.
myAnimal.Run();
But again this is happening relatively rarely. Sorry for the silly Cat & Dog example!
A class is a template for an object. It is essentially a blueprint. So for a light there a button that is on and off. Say when you call this method a value is sent to some controller that turns it on and off. All you have to do is call the method for on/off and viola it works.
An interface is very similar. Here the on/off method might not be implemented. You actually have to go and write the code to turn the light on and off but you must write the on/off method or it cannot be that interface. Say there is a new type of light that has dimming functionality. An interface allows you to implement this new feature for a different type of light. So its basically telling you that you have to have this stuff done (on/off) for it to be a light but we don't care how you implement it. Some parts of the interface may be implemented for you, but other parts you have to implement.
When would an interface make sense? A situation where you have many objects that are very similar in nature but differ slightly in implementation. For example say you have many types of shapes. Each is going to have an area. The calculation is different for a triangle than it is for a circle. Now say you have hundreds of shapes that need to be constructed, you wouldn't keep making new objects for each type of shape, you would just implement the interface. This gives somebody the power to create shapes, maybe even custom shapes, with similar methods but different implementations.
Your answer depends on the way you want to use your future classes. Interfaces are contracts to ensure descendant classes have all definitions of interface. So This is useful when you want to use polymorphism. in this way, you can define all common specifications of an object in an interface class. Another advantage of interfaces is that your class can inherit from multiple interfaces, which is not allowed for other type of classes in C#. Here is an example code. Hope to be useful for you:
public interface IShape
{
float Area { get; }
float circumference { get; }
}
public class Rectangle : IShape
{
private float l, h;
public Rectangle( float length, float height ) { l = length; h = height; }
public float Area { get { return l * h; } }
public float circumference { get { return ( l + h ) * 2; } }
}
public class Circle : IShape
{
private float r;
public Circle( float radius ) { r = radius; }
public float Area { get { return (float)Math.PI * r * r; } }
public float circumference { get { return (float)Math.PI * r * 2; } }
}
public class SomeClass
{
IShape[] shapes = new IShape[] // Can store all shapes regardless of its type
{
new Rectangle( 10f, 20f ),
new Rectangle( 15f, 20f ),
new Rectangle( 11.6f, .8f ),
new Circle( 11f ),
new Circle( 4.7f )
};
public void PrintAreas()
{
foreach ( var sh in shapes )
Console.WriteLine( sh.Area ); // prints area of shape regardless of its type
}
public void PrintCircumference(IShape shape )
{
Console.WriteLine( shape.circumference ); // again its not important what is your shape, you cant use this function to print its cicumference
}
}
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.
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; }
}