Nullable Generic Declaration? - c#

Say I have an object,
Class A<T, T2>
{
public T MyObject {get;set;}
public IList<A<T2>> MyChildren {get;set;}
}
Problem is, sometimes I dont have children, so I dont want to declare the children type aka T2, any idea? I cannot pass in like
A a = new A<string, Nullable>(); as it is throwing an error.
Thanks

There's no way to specify a "null" for a Generic Type parameter - if you declare them on the class, they're mandatory when you use that class.
If you think about it, this makes sense, because without T2, your class will be partially undefined, which isn't something that machines can handle well.
What you probably need to do is to split your class into two. First, your class with no children:
class Widget<T>
{
public T MyObject { get; set; }
}
Then, an extension that adds support for children:
class WidgetWithChildren<T,T2>: Widget<T>
{
public IList<Widget<T>> MyChildren { get; set; }
}
Though, that's only a partial solution, as you don't get a way to handle grandchildren.

Nullable is a genric it self so you have to do something like
new A<string, Nullable<?>>();
You use Nullable to make Value types (e.g. int) able to be null but if you use a Referense Type (e.g. class) it can be null anyway.
My tip is to use a base class for A, if you don't have one use Object.
new A<string, Object>();

Related

Why can't I cast from 1 type to another when both share interface

This is a demo console app (Which you should be able to just copy and paste into VS if you wanted)
public class Program
{
static void Main(string[] args)
{
Temporary t = new Temporary(); //I know it should be ICompany t
t.Name = "My Name";
var com = (ICompany)t;
var result = (Company)com; //Kaboom
}
}
public class Temporary : ICompany
{
public string Name { get; set; }
}
public class Company : ICompany
{
public string Name { get; set; }
}
public interface ICompany
{
string Name { get; }
}
Hopefully the code above is straight forward.
My question is about the cast and why it fails. I know I can change the original variable t to type ICompany (As per the comments), but my quesiton is about why the cast fails as it currently is.
My understanding (which hopefully explains where I'm going wrong) is
var com = (ICompany)t
Cast t, which is of Type Temporary into ICompany. This works great as Temporary implementsICompany`
This means, t is now of type ICompany. So, hopefully
var result = (Company)com; //Kaboom
this converts com (type ICompany) into Company
Why does this fail and why does it know that t is still of type Temporary
There is some confusion in this question, which is probably what prompted it.
This statement:
This means, t is now of type ICompany. So, hopefully
is incorrect. No, t is still of type Temporary, as per its declaration:
Temporary t = new Temporary();
There are actually two places in this line where type is important. It is the actual type of the object you constructed, and the type of the variable you placed the reference into.
Sure, you could write it like this:
ICompany t = new Temporary();
But that would only change the type of the variable, the underlying object is still of type Temporary.
You're then trying to cast the actual object, which is still a Temporary, into a Company, but this will fail, since a Temporary is not a Company.
They both, however, implement the same ICompany interface, which is great, you can talk to both types of objects with only the knowledge that they implement something in common, but it is not the same type of object and you cannot convert from one to another.
Just because com is an ICompany it doesn't mean it points to a Company instance. It could point to a (potentially) infinite number of types that derive from ICompany. Yes, you can look at the code and know this, but that's not how the compiler see it.
This is especially true in your case as the actual type is Temporary, not Company.
You can't just cast the Company class into the Temporary class, because although they both derivate from ICompany and have the same fields, the compiler still thinks that they're different classes. The only allowed kind of class casting is from a child class to its parent class. In that case, you will in fact put a "mask" on the child class which hides its exclusive fields, and that will have it behave as its parent, but you still will be able to convert it back to the original child class.
You cannot cast an interface to a implementation like that. Casting is NOT a conversion. Casting only means: "take this item and treat it as if it was some other type", but the data underneath remains the same. This way you can cast any speciffic type to more general one - the other way is allowed only if object beneath is of type you are casting to (or to some other, iherited type). Imagine that your classes definitions would look like this:
public class Temporary : ICompany
{
public string Name { get; set; }
}
public class Company : ICompany
{
public string Name { get; set; }
public string OtherProperty {get; set;}
}
If you'd call ((Company)t).OtherProperty, you'd try to use a property, that Temporary t object doesn't possess. Compiler does not let you to do so.

Factory pattern with a class that can has different class sub types

I have data from multiple organisations (police, fire, office) that need output in different formats.
To achieve this, I defined the following (this is a little simplified):
Transaction class -
"Success" indicator - Boolean.
"Type of department"- String or Enum.
A class which can be of any type - Police, Fire or Office (My question is on this as you will see).
A GenerateOutput() method - to handle generation of file formats.
Police class
Age - String
VehicleNumber - Integer
Supervisor - String
Fire class
Name - String
FireEngineNumber - Integer
County - Enum
WorkTimings - Enum
Office Class
Age - String
DeskNumber - Integer
Department - String
PayScale - Enum
IsManagement - Bool
As you can see, the Police, Fire and Office classes dont share anything in common and are primarily intended as data carrying entities. I intend to use a Factory to return an appropriate generic (not a C# generic) Transaction object with the data (Transaction object with Police, Fire or Office data within it) and then pass the returned object to a Strategy pattern which determines the file format (CSV, Excel, or XML; specified in a configuration file) each one needs.
My problem is in the definition of the Transaction object.
What type does the class in "3." of the Transaction class need to be? The data for each org differs, there are no common members, I am unable to define a common class for all.
Is the overall design appropriate? What other designs should I consider?
Based on Peter's comments below:
I think using generics might work, I ran into a problem though. I would like to use a factory to return the object requested, using GetTransactionObject, as below. What should be the return type of GetTransactionObject to accomodate this.
class TransactionFactory
{
Dictionary<string, Type> typeClassLookup;
public TransactionFactory()
{
typeClassLookup = new Dictionary<string, Type>();
typeClassLookup.Add("Police", typeof(PoliceData));
typeClassLookup.Add("Fire", typeof(FireData));
}
Transaction<????> GetTransactionObject(string org)
{
if( typeClassLookup.TryGetValue(org, out typeValue))
{
switch (typeValue.ToString())
{
case "policeData":
transactionObject = new Transaction<PoliceData>() { Data = new PoliceData(), params = null};
case "FireData":
transactionObject = new Transaction<FireData>() {Data = new FireData(), params = null};
}
}
return transactionObject;
If the types really have nothing in common, then you need no explicit base class. System.Object suffices, just as with many other generic types (i.e. any generic type lacking a constraint).
In other words, you could declare as:
class Transaction<T>
{
public bool Success { get; private set; }
public T Entity { get; private set; }
public Transaction(bool success, T entity)
{
Success = success;
Entity = entity;
}
public void GenerateOutput() { /* something goes here */ }
}
Personally, I would avoid adding a "department type" member. After all, that's implicit from the type parameter T. But you could add that easily to the above if you want.
If and when you find that the types do have something in common, such that your Transaction<T> type needs to do more than simply hold onto an instance of one of those types (which is about all it can do without a constraint), then you will be able to put that commonality into an interface or base class (depending on the specific need), and specify that in a constraint for the Transaction<T> class.
Note that it's not clear what you mean for the GenerateOutput() to do, or how it should work. But assuming that you want output that is specific for each Entity value, it seems to me that that is your "something in common". I.e., it's not the Transaction<T> class at all that needs to implement that method, but rather each entity type. In that case, you have something like this:
interface IDepartmentEntity
{
void GenerateOutput();
}
class Office : IDepartmentEntity
{
public void GenerateOutput() { /* department-specific logic here */ }
}
// etc.
Then you can declare:
class Transaction<T> where T : IDepartmentEntity
{
public bool Success { get; private set; }
public T Entity { get; private set; }
public Transaction(bool success, T entity)
{
Success = success;
Entity = entity;
}
public void GenerateOutput() { Entity.GenerateOutput(); }
}
EDIT:
Per Prasant's follow-up edit, with a request for advice on the GetTransactionObject()…
The right way to do this depends on the caller and the context, a detail not provided in the question. IMHO, the best scenario is where the caller is aware of the type. This allows the full power of generics to be used.
For example:
class TransactionFactory
{
public Transaction<T> GetTransactionObject<T>()
where T : IDepartmentEntity, new()
{
return new Transaction<T>()
{
Data = new T(),
params = null
}
}
}
Then you call like this:
Transaction<FireData> transaction = factory.GetTransactionObject<FireData>();
The caller, of course already knowing the type it is creating, then can fill in the appropriate properties of the transaction.Data object.
If that approach is not possible, then you will need for Transaction<T> itself to have a base class, or implement an interface. Note that in my original example, the IDepartmentEntity interface has only one method, and it's the same as the GenerateOutput() method in the Transaction class.
So maybe, that interface is really about generating output instead of being a data entity. Call it, instead of IDepartmentEntity, something like IOutputGenerator.
In that case, you might have something like this:
class Transaction<T> : IOutputGenerator
{
// all as before
}
class TransactionFactory
{
public IOutputGenerator GetTransactionObject(string org)
{
if( typeClassLookup.TryGetValue(org, out typeValue))
{
switch (typeValue.ToString())
{
case "policeData":
transactionObject = new Transaction<PoliceData>() { Data = new PoliceData(), params = null};
case "FireData":
transactionObject = new Transaction<FireData>() {Data = new FireData(), params = null};
}
}
return transactionObject;
}
}
This is an inferior solution, as it means the caller can only directly access the IOutputGenerator functionality. Anything else requires doing some type-checking and special-case code, something that really ought to be avoided whenever possible.
Note: if the Transaction type has other members which, like the GenerateOutput() method, are independent of the contained type T here, and which would be useful to callers who don't know T, then a possible variation of the above is to not reuse the interface used for the department-specific data types, but instead declare a base class for Transaction<T>, named of course Transaction, containing all those members not related to T. Then the return value can be Transaction.
What type does the class in "3." of the Transaction class need to be?
To decouple your department classes from the various export types, I recommend you make the department classes implement a common interface. Something like this:
public interface Exportable {
// return a list of attribute names, values, and types to export
IList<Tuple<String, String, Type>> GetAttributes();
}
For example:
public class Police : Exportable {
public IList<Tuple<String, String, Type>> GetAttributes() {
// return list size 3 - attribute info for Age, VehicleNumber, Supervisor
}
}
Is the overall design appropriate? What other designs should I consider?
The Transaction class design doesn't seem well suited for this problem.
Consider an Export class with a method for each export type, each method which receives the attributes returned from the Exportable interface method. Basic outline:
public static class Export {
public static boolean CSV(IList<Tuple<String, String, Type>> attributes) {
// export attributes to CSV, return whether succeeded
}
public static boolean Excel(IList<Tuple<String, String, Type>> attributes) {
// export attributes to Excel, return whether succeeded
}
// same thing for XML
}

Distinguish class property types through reflection

I have a Rectangle class
public class Rectangle : Base, IRectangle
{
public IDimension dimension { get; set; }
public Position position { get; set; }
public String color { get; set; }
public int ID { get; set; }
public override String ToString()
{
return base.ToString(this);
}
}
Are there any way to distinguish through reflection types of properties which defined on Rectangle class?
How can I understand ID is struct or dimension is Interface? And Both String and Position are class but String is build in class, Position is Custom class.
You can use this property:
typeof(T).IsPrimitive
To check if a type is primitive or non-primitive
This one:
typeof(T).IsInterface
To check if a type is an interface or not.
This is how you check is a type is a struct or not:
typeof(T).IsValueType
In case you are truly looking only for "pure" structs (not just value types in general) then:
typeof(T).IsValueType && !typeof(T).IsEnum;
var prop = typeof(Rectangle).GetProperty("ID");
if(prop.PropertyType.IsValueType)
{
..
}
prop = typeof(Rectangle).GetProperty("dimension");
if(prop.PropertyType.IsInterface)
{
...
}
prop = typeof(Rectangle).GetProperty("color");
if(prop.PropertyType.IsClass)
{
...
}
As you might have noticed Type class contains several properties that you can determine whether the type is a value type,or interface or class etc.
To determine whether the class type is built-in type or custom type, I think you can check whether type's Assembly is loaded from the GAC (Global assembly cache) or not.It's not the best solution but I don't know another way.
if(prop.PropertyType.Assembly.GlobalAssemblyCache)
{
// built-in type..
}
the above answer are good.
BUT
if you something that is extensible, you can create your own custom Custom Attributes and use reflection on that Type.
For example, you can create attribute that's contain how to print properties or how to validate them, get those all with reflection.
we use this way to create protocol parser, where each properties we define the order in the protocol, the length, and the validation - But again - this can be over killer for you

C# return a variable as read only from get; set;

I swear I have seen an example of this but have been googling for a bit and can not find it.
I have a class that has a reference to an object and need to have a GET; method for it. My problem is that I do not want anyone to be able to fiddle with it, i.e. I want them to get a read only version of it, (note I need to be able to alter it from within my class).
Thanks
No, there's no way of doing this. For instance, if you return a List<string> (and it's not immutable) then callers will be able to add entries.
The normal way round this is to return an immutable wrapper, e.g. ReadOnlyCollection<T>.
For other mutable types, you may need to clone the value before returning it.
Note that just returning an immutable interface view (e.g. returning IEnumerable<T> instead of List<T>) won't stop a caller from casting back to the mutable type and mutating.
EDIT: Note that apart from anything else, this kind of concern is one of the reasons why immutable types make it easier to reason about code :)
Return a reference to a stripped-down interface:
interface IFoo
string Bar { get; }
class ClassWithGet
public IFoo GetFoo(...);
If the object isn't too complicated/extensive then write an wrapper around it.
for example:
class A {
public string strField = 'string';
public int intField = 10;
}
class AWrapper {
private A _aObj;
public AWrapper(A aobj) {
_aObj = A;
}
public string strField {
get {
return _aObj.strField;
}
}
public int intField {
get {
return _aObj.intField;
}
}
}
So now all you do is give your client code an instance of the AWrapper class so that they may only use what you allow them to see.
this may get a bit complicated and may not scale well if your base class is not set in stone, but for most simple situation it may just do the trick. I think this is called a facade pattern(but don't quote me on that =) )
This isn't possible. Get and set accessors to reference types get and set the reference to the object. You can prevent changes to the reference by using a private (or internal) setter, but you cannot prevent changes to the object itself if it's exposed by a getter.
Your question reads like you're looking for:
public PropertyName { get; private set; }
But then, given the answers so far I'm not sure I'm interpreting your question correctly. Besides, who am I to question Jon Skeet? :)
i agree with ReadOnlyCollection
See my simple code:
private List<Device> _devices;
public readonly System.Collections.ObjectModel.ReadOnlyCollection<Device> Devices
{
get
{
return (_devices.AsReadOnly());
}
}
ReadOnlyCollection dosen't has Add method so user cant add properties to it.BUT ther is no warranty that if user can modify objects by calling their methods....
I have faced this problem in a certain way.
I have a CategoryViewModel class, which have a property Category that I want private read-only :
public CategoryViewModel
{
private Category { get; }
}
In fact, I want it to be exported as read-only to other class. However I can't do such thing.
In my case (maybe it will help some other guys), I want to add it to a repository. The only way that I've found is to have a function with the repository as param 1, and an Action as param 2 :
public void ApplyAction(ICategoryRepository repo, Action<ICategoryRepository, Category> action)
{
action(repo, Category);
}
Like that, from elsewhere, I can do such thing :
categoryViewModel.ApplyAction(_repository, (r, c) => r.MarkForInsertOrUpdate(c));
This can help other to expose there property only for certains cases and can manage them.

Property type depends on enum value

How should i implement, in C#, a class containing a property with the type of something and then that something example :
public class MyObject{
public someEnum e { get; set;}
public Object ObjectDependentOnE { get; set; }
}
I want to be able to return the right type for my object which depends on my enum.
for example if e = 1, my object is of type T1...
or maybe I trying to do somethng wrong
any idea?
I am unsure of what you are really trying to do, but it appears that generics is what you are looking for:
public class MyObject<T>
{
public T SomeProperty{get;set;}
}
You can constraint T to classes that implement a given interface.
Usage would be:
MyObject<SomethingClass> something = new MyObject<SomethingClass>;
I'm not sure what your use case would be - more information might help answer this better, but from my guess, you may want to consider making a factory class instead. Something like:
class MyClass
{
public SomeEnum E { get; set; }
// This might be better as : public Object GetTheObject(SomeEnum E) and eliminating the above property
public Object GetTheObject()
{
switch(this.E)
{
case E.Something:
return new MySomethingObject(); // Or return an instance that already exists...?
default:
return new MyDefaultObject();
}
}
}
This could also be a property with a getter and setter, and get and set the specific object type.
However, I recommend considering rethinking the approach - this seems like a very error-prone design, since it has no type safety at compile time, and is very confusing from the consumer's POV.

Categories