Using a dynamic type instead of non-possible common properties

Consider the following code:

public dynamic DataGrid { get; private set; } public DataGridForm<TData, TGrid> GridConfig<TData, TGrid>() where TData : class { return DataGrid = new DataGridForm<TData, TGrid>(); } 

I am trying to save an instance of a generic class in property for later use, but as you know:

Properties, events, constructors, etc. cannot be shared - only methods and types can be shared. Most of the time this is not a problem, but I will agree that sometimes it’s a pain ( Jon Skeet )

I want to know is this a good way to get around this?

+6
source share
2 answers

As the answer in the specified comment, you can do this using the base class or interface:

 class DataGridForm {} class DataGridForm<TData, TGrid> : DataGridForm {} class GridConfigurator { public DataGridForm DataGrid { get; private set; } public DataGridForm<TData, TGrid> GridConfig<TData, TGrid>() where TData : class { return DataGrid = new DataGridForm<TData, TGrid>(); } } 

A ton of types and interfaces in C # was expanded this way when generics were added. However, I would probably overestimate your design, so perhaps everything called GridConfig () cached the DataGridForm as it knows the types. As an example, I am doing very similar in my code:

 class Vector<T> { ... } static class Vector { public static Vector<T> Create<T>(T value) { return new Vector<T>(value); } } class OtherClass { public static Vector<int> MyVector = Vector.Create(1); } 

However, your specific use case may not support this style.

+1
source

In this case, your type itself should be common.

  class GridConfigurator<TData, TGrid> where TData : class { public DataGridForm<TData, TGrid> DataGrid { get; private set; } public DataGridForm<TData, TGrid> GridConfig<TData, TGrid>() { return DataGrid = new DataGridForm<TData, TGrid>(); } } 

But I do not understand the purpose of this class. The GridConfig method has an unobvious side effect of setting the DataGrid property (which has a private setter). If I used this class, I would never have guessed that the value returned to me by GridConfig () is also set as a DataGrid property. In other words:

 var configurator = new GridConfigurator(); var firstGrid = configurator.GridConfig(); var firstReference = configurator.DataGrid; var secondGrid = configurator.GridConfig(); var secondReference = configurator.DataGrid; 

I would suggest that the following returns false:

 object.ReferenceEquals(firstGrid, secondGrid); 

But I would suggest that this will return true :

 object.ReferenceEquals(firstReference, secondReference); 

Because in no case in the above code I never assign the DataGrid property. It is not clear that the GridConfig () method would have such an effect.

Creating a closing type (GridConfigurator) also tends to hit the target of what you are trying to do. Why would anyone use this type if they can just use the direct link to the DataGridForm?

If the GridConfig method needs to do more than just assign a new instance of the DataGridForm by default, then make it a static factory class as follows:

 static class GridConfigurator { public static DataGridForm<TData,TGrid> GridConfig<TData, TGrid>(...) where TData: class { var grid = new DataGridForm<TData,TGrid>(); // do something with the parameters to this method to initialize the instance. return grid; } } 

I would also call the method something other than GridConfig. Like Configure () or Create ().

0
source

Source: https://habr.com/ru/post/950190/


All Articles