I have two classes with similar fields:
Class Foo {
string name;
int val;
};
Class Bar {
string name;
int val;
};
Is there a way to use Generics to retrieve the field names and values of objects of these classes? Something along the lines of:
string GetName<T> (T obj)
{
//returns T.name
}
I want to make sure there are compile time checks for this, in case the class fields were to change.
Update:
I do not control the definitions of classes Foo and Bar. They will be exposed to me in a library and can change.
I can use something like the following:
Type myType = myObject.GetType();
var value = myType.GetProperty("name").GetValue(myObject, null);
But I don't think this would check at compile time.
If you want compile-time safety, and you can't modify Foo and Bar, the typical way to deal with this is with overloads:
public string GetName(Foo o) { return o.Name; }
public string GetName(Bar o) { return o.Name; }
The compiler will automatically pick the method that matches the type of the parameter, so you just need to call it with
GetName(eitherObject);
...and it's type-safe.
You can't really use generics because Foo and Bar lack a common interface that exposes Name.
You can use Reflection, of course, but that means abandoning compile-time safety.
This seems to be a case where you could use inheritance. If these two classes have similar fields you could make them implement a base class which has all the shared fields. Here is an example:
public class BaseEntity
{
int val;
protected string name;
public string Name
{
get
{
return name; // Only get is exposed to prevent modifications
}
}
}
public class ClassA : BaseEntity
{
// Other fields or methods
}
public class ClassB : BaseEntity
{
// Other fields or methods
}
Related
Yesterday, I was explaining C#'s generic constraints to my friends. When demonstrating the where T : CLASSNAME constraint, I whipped up something like this:
public class UnusableClass<T> where T : UnusableClass<T>
{
public static int method(T input){
return 0;
}
}
And was really surprised to see it compile. After a bit of thinking, however, I figured it was perfectly legal from the point of view of the compiler - UnusableClass<T> is as much of a class as any other that can be used in this constraint.
However, that leaves a couple of questions: how can this class ever be used? Is it possible to
Instantiate it?
Inherit from it?
Call its static method int method?
And, if yes, how?
If any of these is possible, what would the type of T be?
This approach is widely used in Trees and other Graph-like structures. Here you say to compiler, that T has API of UnusableClass. That said, you can implement TreeNode as follows:
public class TreeNode<T>
where T:TreeNode<T>
{
public T This { get { return this as T;} }
public T Parent { get; set; }
public List<T> Childrens { get; set; }
public virtual void AddChild(T child)
{
Childrens.Add(child);
child.Parent = This;
}
public virtual void SetParent(T parent)
{
parent.Childrens.Add(This);
Parent = parent;
}
}
And then use it like this:
public class BinaryTree:TreeNode<BinaryTree>
{
}
Well.
public class Implementation : UnusableClass<Implementation>
{
}
is perfectly valid, and as such makes
var unusable = new UnusableClass<Implementation>();
and
UnusableClass<Implementation>.method(new Implementation());
valid.
So, yes, it can be instantiated by supplying an inheriting type as the type parameter, and similarly with the call to the static method. It's for instance useful for tree-like structures where you want to generically specify the type of children the node has, while it being the same type itself.
If any of these is possible, what would the type of T be?
They are all possible, and you are the one who is gonna determine what is the type of T.For example let's assume there is a type that inherits from UnusableClass<T>
class Foo : UnusableClass<Foo> { }
Now you can instantiate UnusableClass<Foo> because Foo satisfies the constraint:
UnusableClass<Foo> f = new UnusableClass<Foo>();
Then the type of T become Foo and if you try to call method you need to pass an instance of Foo.
The following question shows how to implement an interface that contains a class in java:
inner class within Interface
The code in Java is:
public interface A {
class B {
}
}
I was hoping the same thing was possible in C#, though I haven't yet been able to get anything working.
For reference, I have a class which makes lookups of key values, but the keys aren't named in a way that makes them easy to understand. I'd like to have a compile time lookup for keys, so the interface would be something like:
interface Lookup {
class Keys {
string SomeKey() => "0"
}
}
Which means I suppose I have two questions:
Is it possible to have an interface containing a class?
Is there a better way of having a lookup between two strings (or any other values) that I can reference reliably at compile time?
Simply put no you can't have a class inside an interface.
From your comments you are talking about having a restricted list of available strings for the keys so I'm wondering if you are in fact not looking for a string/string lookup but just want a convenient way of referencing a list of fixed strings. So a class with constants is all you need:
public static class Strings
{
public const string AString = "A";
public const string BString = "B";
public const string CString = "C";
}
Accessed like this:
var s = Strings.AString;
You cannot have an class within an interface in C#. Interfaces are very simple in C#, and only provide a contract of functionality.
If you want to have a mapping between two strings, a Dictionary<string, string> may be of use to you.
An interface can't itself have any instance data. It's implementation however can have any instance data it requires.
For example, a random example that might give you some insight:
public class SomeClass
{
public string Key {get; set;}
}
public interface ISomeInterface
{
string Value { get; set; }
SomeClass SomeClass { get; set;}
}
public class SomeInterfaceImplementation : ISomeInterface
{
public SomeInterfaceImplementation()
{
SomeClass = new SomeClass()
{
Key = "ABC"
};
}
public string Value { get; set; }
public SomeClass SomeClass { get; set; }
}
public class Program
{
public static void Main()
{
var example = new SomeInterfaceImplementation()
{
Value = "A value",
} as ISomeInterface;
Console.WriteLine($"{example.SomeClass.Key} has value '{example.Value}'");
}
}
In the example, the default constructor "generates" a key of ABC. We could implement this any way your logic requires. But you also have a contract that requires "SomeClass" and it's key is present.
Anywhere you want to use the contract, just accept the Interface and not an implementation class.
Additionally, feel free to play with the fiddle:
Most of the answers under this question are no longer true.
Since C# 8.0, when default interface methods were added, it is possible for an interface to have member declaration that declare for example nested type.
The following code is correct for C# 8.0:
public interface IA
{
class B
{
}
}
I have a set of classes that derive one from another and the lower level has complete structure of what i need. the data stored and save is the highest level. in the highest level the Type is stored in the object. how can i cast down the highest level to the lowest. the generic see highest and T is highest which isn't helpful.
example :
Head class with couple core methods/fields :
[Serializable()]
public class CSelectionProperties
{
private Dictionary<string, string> lstProperties = new Dictionary<string, string>();
public Dictionary<string, string> getProperties { get { return lstProperties; } }
private Type objectType = null;
public Type ObjectType { get { return objectType; } set { objectType = value; } }
internal string FindProperty(string sProperty)
{
return FindProperty(sProperty, null);
}
internal string FindProperty(string sProperty, string sNullValue)
{
string sValue = sNullValue;
lstProperties.TryGetValue(sProperty, out sValue);
}
}
here an example of one of the many derived class :
[Serializable()]
public class CFilterSelectionProperties : CSelectionProperties, IFilterSelectionProperties
{
public double getAirVolume()
{
return Convert.ToDouble(FindProperty("INCFMValue", "0"));
}
}
Now all object using these property have the variable as CSelectionProperties so we can reuse everywhere same format.
When a class such as CFilterSelectionProperties gets created the Type get stored into the CSelectionProperties.ObjectTypeas a Type now another project receive a collection of CSelectionProperties and to properly read them i need to cast them as the proper type.
Right now i am going the old way
If(item is CFilterSelectionProperties)
{
RunDataAnalysis(item as CFilterSelectionProperties);
}
Else If (item is ...)
{
RunDataAnalysis(item as ...);
}
i use reflection and i stumble upon a case where i need the actual original class to loop the methods and retrieve some data. is there any way ?
Also some report will need to be open but again i have 4 class that derive from 1 single class that derive from CSelectionProperties at which point i don't have access to anything at all. I'm just trying to get away from If/Else which works fine.
As side note i tried going with and Activator but i can only find how to recreate a class as child type.
CFilterSelectionProperties oItem = new CFilterSelectionProperties();
MyObject.SelectionProperties = Activator.CreateInstance(oItem.ObjectType) as CSelectionProperties;
Not exactly sure if this is what you need but you can have a base class that "knows" the derived type:
class MyBase<T> {}
class A : MyBase<A> {}
class B : MyBase<B> {}
this way you can do this:
void Foo(MyBase<T> baseObj)
{
T derived = (T)(object)baseObj;
// use derived in a strongly-typed manner
}
Without knowing what RunDataAnalysis does it sounds like you can use virtual (or abstract) methods/properties in the base class that are overloaded in the derived classes. Then when you call those methods/properties in RunDataAnalysis you will be using the most derived version without having to cast the variable.
For example:
public class CSelectionProperties
{
... existing stuff
public virtual DataSet GetData(.. some parameters ...)
{
.. do stuff common to ALL subtypes
}
}
and
public class CFilterSelectionProperties : CSelectionProperties, IFilterSelectionProperties
{
public override DAtaSet GetData(... some parameters ...)
{
... do stuff common to THIS type and subtypes
}
}
stackoverflow. I'm new to C#, but have experience in C++ and I got stuck with one idea realization:
I want to make an object with abstract properties(not C# properties, but variables) as a base class and N derived classes with such inheritance:
ObjWithProps <-- A <-- B <-- N other classes derived one from another
Properties list is static, so it will be initialized once per type, not per object. Each of A and B can add own abstract properties with unique string-represented names. First of all I was thinking of making it with OpenInstanceDelegates, but it turns out, that delegates can't be covariant, am I right ?
public delegate T OpenGetterDlg<T>(ObjWithProps instance);
I can't simply bind function A.GetSomething() to OpenGetterDlg because of different this parameter and covariance doesn't works here.
I could do that instead:
public delegate TPropType OpenGetterDlg<TPropType, TThisType>(TThisTypeinstance);
but it becomes real pain in the ass when dealing with a list of
class CPropWrapper<TPropType, TInstType> where TInstType : ObjWithProps
{
// Property ID here
// Setter Delegate object here
// Getter Delegate object here
}
Too many casts, too many type params, too many templates ... Maybe someone knows how do that task in C# ? The key ideas: static prop list, any derived classes (A, B, C, D) can add their own props to list, encapsulated and minimal type specification.
Thanks in advance!
UPD1:
Pseudocode
class ObjWithProps
{
class CPropertyWrapper
{
public string Name;
public OpenGetterDelegate Getter;
public OpenSetterDelegate Setter;
}
static List<CpropertyWrapper> AbstractProps;
public CProperty GetPropertyByName(string name)
{
// Find property by name and
return PropertyFromType(Getter());
}
}
CProperty is a base wrapper class for types like int, float, myType1, myType2.
class A: ObjWithProps
{
int IQValue;
public int getIQ() { return IQValue; }
public void setIQ(int iq) { IQValue = iq; }
protected override registerProps()
{
// this one should be called only once
registerProperty<int>("IQ", "getIQ", "setIQ");
}
}
class B: A
{
myType1 X;
public myType1 getX() { return X; }
public void setX(myType1 x) { X= x; }
protected override registerProps()
{
base.registerProps();
registerProperty<myType1>("X", "getX", "setX");
}
}
At first look, you want to re-invent dependency properties from WPF. At least, I can't see any conceptual differences.
What I basically wish to do is design a generic interface that, when implemented, results in a class that can behave exactly like T, except that it has some additional functionality. Here is an example of what I'm talking about:
public interface ICoolInterface<T>
{
T Value { get; set; }
T DoSomethingCool();
}
public class CoolInt : ICoolInterface<int>
{
private int _value;
public CoolInt(int value)
{
_value = value;
}
public int Value
{
get { return _value; }
set { _value = value; }
}
public int DoSomethingCool()
{
return _value * _value;
// Ok, so that wasn't THAT cool
}
}
And this is all well and good, but in order to use CoolInt, I need to do something like this:
CoolInt myCoolInt = new CoolInt(5);
int myInt = myCoolInt.Value;
I'd much rather, in terms of assignment at least, that CoolInt works just like int. In other words:
CoolInt myCoolInt = 5;
int myInt = myCoolInt;
To achieve this, I added these two conversion operators to my CoolInt class:
public static implicit operator CoolInt(int val)
{
return new CoolInt(val);
}
public static implicit operator int(CoolInt obj)
{
return obj.Value;
}
Works awesomely. Now, I would prefer it if I could add these two overloads to the interface, so that implementers of the interface are forced to implement these operators. The problem is, the prototypes of these operators refer directly to CoolInt.
C# has a lot of "placeholder" names for things that are implicitly defined or have yet to be defined. The T that is conventionally used in generic programming is one example. I suppose the value keyword, used in Properties, is another. The "this" reference could be considered another. I am hoping that there's another symbol I can use in my interface to denote "the type of the class that is implementing this interface", e.g. "implementer".
public static implicit operator implementer(int val)
{
return new IntVal(val);
}
public static implicit operator int(implementer obj)
{
return obj.Value;
}
Is this possible?
Why don't you create an abstract class? This way you can build some "default" functionality into your class.
Sadly no :(
C# doesn't do well when it comes to operator overloading (This is one example, another is generic constraints on certain operator types).
Why not use extension methods instead? That lets you "add" methods to int without having to use a different type.
This is probably the closest you can get using an abstract base type, but sadly even this has an issue with one of the implicit operators and you have to do:-
CoolInt x = (CoolInt)5;
int j = x;
Close enough?
// Slightly sneaky, we pass both the wrapped class and the wrapping class as type parameters to the generic class
// allowing it to create instances of either as necessary.
public abstract class CoolClass<T, U>
where U : CoolClass<T, U>, new()
{
public T Value { get; private set; }
public abstract T DoSomethingCool();
// Non-public constructor
protected CoolClass()
{
}
public CoolClass(T value)
{
Value = value;
}
public static implicit operator CoolClass<T, U>(T val)
{
return new U() { Value = val};
}
public static implicit operator T(CoolClass<T, U> obj)
{
return obj.Value;
}
}
public class CoolInt : CoolClass<int, CoolInt>
{
public CoolInt()
{
}
public CoolInt(int val)
: base(val)
{
}
public override int DoSomethingCool()
{
return this.Value * this.Value; // Ok, so that wasn't THAT cool
}
}
It would be helpful if, at least for interfaces, one could declare that a class implements an interface in terms of an object; this would be especially cool if there was an "interface" generic type constraint. Then one could, for example, do something like (VB syntax)
Class Foo(Of T as Interface)
Implements T via Bar ' Declares variable 'bar' of type T
Sub DoSomething
' Does something
End Sub
End Class
and then cast a Foo(of T) to a T and have it behave like a T. Maybe someone from MS can stumble on the idea and pass it on?
I should note, btw, a nice pattern similar to your ICoolInterface:
public interface ISelf<T>
{
T Self { get;}
}
public interface IFoozle
{
... definitions for IFoozle
}
public interface IFoozle<T> : ISelf<T> , IFoozle;
{
/* Empty except for above declarations */
}
... similarly define IWoozle and IWoozle<T> etc.
Then one can declare a field which can implement IWoozle and IFoozle, and inherits from BoozleBase (which implements neither), via:
IWoozle<IFoozle<BoozleBase>> myField1;
or
IFoozle<IWoozle<BoozleBase>> myField2;
Note that the above two types can be cast to each other, or to types which also contain other interfaces. If one only needs to pass a variable meeting multiple constraints to a method, one can obtain such a thing more easily by using a generic method. Unfortunately, there's no way to store an object of unknown type in a field in such a way that it can be passed to a generic function with multiple constraints.