I have a question if Resharper can help me with below problem.
Let's say there is a class with many properties inside:
public class TestClass {
public string variableA {get; set;}
public string variableB {get; set;}
public int variableC {get; set;}
}
then somewhere else we have a method that uses TestClass object
public void TestMethod(TestClass classInstance) {
classInstance.variableA = 'new value';
classInstance.variableC = 1;
}
of course this example is much simplified to the one I have, but I want somehow to extract interface that will have only
variableA
variableC
because then I want to pass it as a parameter to TestMethod. Can ReSharper do it automatically?
Right click the class
Select Refactor -> Extract -> Extract interface.
It takes you to extract interface window, in which you can select all the properties you want to extract it to a new interface.
In visual studio keyboard scheme shortcut happens to be ctrl + shift + R, x or select "Extract interface".
Once this refactoring is done, it is simply the matter of changing the method's formal parameter to use your interface as opposed to the concrete type.
I did what I wanted and I want to share solution, or maybe better say small workaround.
first what I did was to create an interface that contained all properties from the TestClass.
I changed method signature to get this interface instead of class itself.
I turned on wide analysis in R# and checked which properties are not used and removed them from the interface.
Maybe someone will need this in future when refactoring. Anyway - thanks for your help!
Related
I want to create a little testing tool for my program, which fills all properties of a random object (unknown type at compile time). A sample structure:
public class HeadObject
{
public Company Company { get; set; }
public CompanyAddress CompanyAddress { get; set; }
public List<Details> Details{ get; set; }
public ApplicationUser AppUser { get; set; }
}
and e.g the class Company would look like this:
public class Company
{
public string CompanyName{ get; set; }
public string PhoneNumber{ get; set; }
public Address Adress{ get; set; }
public int CompanyNo{ get; set; }
public List<Employee> Employees{ get; set; }
}
its pretty simplified because in each HeadOjbect there are around 30 properties which may contain sub properties or a property can be a list etc.. I need to populate ~30 HeadObjects at runtime. I already tried it with different libraries like GenFu, nBuilder or Bogus.
The last 2 have the problem that I have to fill the properties by myself only the data is generated. GenFu looks like it can only deal with primitive properties like int, string, ... And if you imagine the HeadObject as a root of a tree, then there would be
~ 300 Nodes per tree
Height of a tree: between 1 and 7(!)
~30 Different trees (HeadObjects)
so it would take days to write this all down by myself and maintenance would be a pain.
I appreciate any kind of idea.
UPDATE
Thanks for your replies! How can I initialize the objects? e.g I get the Company property of my head object and then I want to initialize it to be able to fill it. My method (its recursive) starts like this:
private static T FillAllProperties<T>(T masterObject) where T : new()
{
try
{
Type masterType = masterObject.GetType();
T headObject = new T();
......IF primitive Type fill it and return the value
otherwise get Properties into firstProperties.......
foreach (var propertyInfo in firstProperties)
{
var objectInstance = FillAllProperties(propertyInfo.PropertyType);
headObject.GetType().GetProperty($"{propertyInfo.Name}").SetValue(headObject, objectInstance, null);
}
Now I have 2 questions:
is my way to initialize the generic type correct?
at the recursive call I get the following error :" The type 'System.Type' must have a public parameterless constructor in order to use it as parameter 'T'....
I probably need another "construction" for this algorithm, but how..?
You are going to go through deep pain...
Basically the idea is to iterate through the object's properties and randomly fill them.
You can iterate using YourObject.GetType().GetProperties() then using PropertyInfo.PropertyType to know the type.
Then with each Proprety Type you can check whether it is a simple (i.e. int, double...) structure or a more complex object (by using Type.IsPrimitive, Type.IsClass or Type.IsValueType).
If it a class, you recursively call the same method, because it means you have a complex type.
If it is a structure, then maybe you should iterate over the fields instead of the properies ?
If it is a primitive you can set its value using PropertyInfo.SetValue(), but how are you going to randomize anything ? You need to perform a switch on .Net base types then generate a value at random for each type.
By the way, a string is a class, not a primitive, so you will need to make a special case for this one.
Also, List<string> is a funny one, because it is an Enumerable object. So it is another specific case.
And if you want to have fun, try out a Dictionary, or better, Tuple...
Anyway, there is no simple way to perform this. Your simple testing tool will soon become a nightmare because of all the cases you couldn't even see from far away...
Maybe there is a better option to test your program than filling it with random values that don't have any actual meaning ?
If you do not know the properties at runtime, you will have to use Reflection. But starting with 30 properties, I would probably use it regardless (or look if I made any mistakes in my design). Writing that much manually is just too prone to mistakes.
A alternative might be to have a ISelfRandomizing interface with a SelfRandomize() function, so each type input can carry it's own randomization code. And hope people actually provide it.
Something that might be viable for your case: structs by default use reflection for comparison. What would be the equivalent of a base class for them, has reflection based fallback code. You are invited to override it, but if you do not it just "works". You could make a abstract base class that you use for all those classes. That way you only need to write the reflection code once.
As for the actual randomization: Random. A common mistake is creating new instances of Random in a loop. Do not do that. You want to keep a single Random instance around as long as possible, for optimal randomisation. I have no sensible way to transform a Integer return into a string, so the next best non-sensible thing is to create a large random number and call ToString() on it. That will give you something to put in those spots at least.
I'm using a thousand instances of a closed DllClass in my project.
public sealed class DllClass
{
public DllClass();
public string DllClassProperty {get; set;}
}
DllClassProperty set is used a thousand of times and I need to override the value set if a parameter is set on Web.config.
I found this Interface INotifyPropertyChanged, but I can't use it, because I don't have access to the class and I can't extend it.
I'm thinking, if there's a way to do something like this, but I think this is not possible in C#:
public class OnSetPropertyListener<DllClass>
{
public void OnSetProperty(PropertyInfo propertyInfo, DllClass instance)
{
// set another value, for example: "new value"
}
}
How can I override the value set in DllClassProperty? Is it possible?
Surprisingly, there is a way to solve your problem. It's not pretty, but it satisfies the constraints of your question.
Step 1: Create a wrapper around DllClass, i.e. a new class MyDllClassWrapper, which behaves exactly like DllClass except for the change that you want to implement. This is usually done by rebuilding the public interface of DllClass and just forwarding all operations to a private DllClass instance.
Now you just need to use MyDllClassWrapper everywhere where you currently use DllClass. You mentioned in the comments that you don't want to change all those calls, so let's automate that:
Step 2: Use Substitute.Fody to automatically replace all references to DllClass by references to MyDllClassWrapper in a post-compile step:
[assembly: Substitute(typeof(DllClass), typeof(MyDllClassWrapper))]
Note, though, that everyone reading your code will be thoroughly confused, since the source code points to DllClass, but MyDllClassWrapper is used instead. Thus, I recommend that you use this technique only as a temporary workaround until you find the time to cleanly replace all references to DllClass with references to MyDllClassWrapper.
Can VS 2012 professional generate a class constructor without any addons?
I can't believe I can't find the option to do this, and if it can't do it, it truly is a conspiracy :)
I have my class defined:
public class User
{
public int Id {get;set;}
public string Name {get;set;}
}
Now is there a shortcut that will generate the constructor, toString() method etc?
If you need a default constructor then there is a code snippet ctor for it.
But if you need a constructor with parameters then in you code write:
User user = new User(2, "Name");
This will be an error, since there is no constructor with two parameters, but you will get a blue under line if you hover your mouse over User in new User. Click on that or put your cursor on User and press Ctrl + . It will give you an option to generate constructor like:
That will give you a constructor with fields like:
public class User
{
private int p1;
private string p2;
public User(int p1, string p2)
{
// TODO: Complete member initialization
this.p1 = p1;
this.p2 = p2;
}
public int Id { get; set; }
public string Name { get; set; }
}
Then you have to go in and remove p1, p2 and point to Id, Name and also rename parameters in constructor. That is probably the best you can do with only Visual studio.
See: Generate From Usage - MSDN (thanks to #Peter Ritchie)
Consider installing Re-Sharper it has much better option for generating not only constructor but other very helpful code.
snippets are built in and you can add your own. ctor will make the constructor, I don't think there is anything for ToString, though you can just type override, pick it from the list and it will stub it out.
"ctor" snippet generates a constructor, but without parameters. To get them, you should unfortunately use (free or not) addons. This question has been already discussed, see Shortcut for creating constructor with variables (C# VS2010) for example.
I think there is no direct mean to generate a paramerized constructor in a bare Visual Studio.
Edit : I should probably have added after my last sentence "... which strictly applies to properties and fields currently defined in class". But yes, following Peter's advice it is possible to generate a kind of parameterized constructor.
I need to hide few methods inside a class based on the parameter that is passed to the constructor in c#. How would I do this?
Thanks in advance!
More Info:
I was part of this GUI development where they had a API with access to registers in a hardware. Now they are releasing a newer hardware so I need to support both old and new one which has a newer API(Mostly duplicate of old one with some old removed and some new registers added).
Moreover, I need to keep this only one class called "API" as we used it in many places. So the idea of using a newer API with a different name was ruled out.
Now finally, I got this idea of including the newer one into old one with just conditionally hiding the registry access methods.
You can't toggle the visibility of members..... the best bet is to have different interfaces that hide the members.
public interface IName
{
string Name { get; set; }
}
public interface INumber
{
string PhoneNumber { get; set; }
}
public class Worker : IName, INumber
{
public string Name { get; set; }
public string PhoneNumber { get; set; }
}
So either use Worker through the IName or the INumber interface and it will hide the other members on the class....
I think you might be looking at a re-factor here. Try making a base class with all the methods / properties that behave the same regardless of the parameter, then two child classes which behave differently. Also have a look at the class factory pattern.
You will need to restructure the code into multiple classes or interfaces. You can't dynamically change the visibility level of class members based on a parameter value. Members are construction time information not run time.
You can't change visibility of methods, but you can pass parameter to the single method and do some logic depending on your parameter by using switch - case. But it depends on your method structure.
Try to review your class and change its design. Maybe you can find any design pattern that will help you.
You may actually do something alike using Dynamic code generation, although this is more like a hack than actual code that should be used in production.
Maybe if you explain why you need this then you may get more relevant answers.
My searches keep turning up only guides explaining how to use and apply attributes to a class. I want to learn how to create my own attribute classes and the mechanics of how they work.
How are attribute classes instantiated? Are they instantiated when the class they are applied to is instantiated? Is one instantiated for each class instantiated that it is applied to? E.g. if I apply the SerializableAttribute class to a MyData class, and I instantiate 5 MyData instances, will there be 5 instances of the SerializbleAttribute class created behind the scenes? Or is there just one instance shared between all of them?
How do attribute class instances access the class they are associated with? How does a SerializableAttribute class access the class it is applied to so that it can serialize it's data? Does it have some sort of SerializableAttribute.ThisIsTheInstanceIAmAppliedTo property? :) Or does it work in the reverse direction that whenever I serialize something, the Serialize function I pass the MyClass instance to will reflectively go through the Attributes and find the SerialiableAttribute instance?
I haven't use attributes in my day-to-day work before, but I have read about them.
Also I have done some tests, to back up what I'll say here. If I'm wrong in any place - feel free to tell me this :)
From what I know, attributes are not acting as regular classes. They aren't instantiated when you create an object that they are applied to, not one static instance, not 1 per each instance of the object.
Neither do they access the class that they are applied to..
Instead they act like properties (attributes? :P ) of the class. Not like the .NET class properties, more like in the "one property of glass is transparency" kind of property. You can check which attributes are applied to a class from reflection, and then act on it accordingly. They are essentially metadata that is attached to the class definition, not the objects of that type.
You can try to get the list of attributes on a class, method, property, etc etc.. When you get the list of these attributes - this is where they will be instantiated. Then you can act on the data within these attributes.
E.g. the Linq tables, properties have attributes on them that define which table/column they refer to. But these classes don't use these attributes. Instead, the DataContext will check the attributes of these objects when it will convert linq expression trees to SQL code.
Now for some real examples.. I've ran these in LinqPad, so don't worry about the strange Dump() method. I've replaced it with Console.WriteLine to make the code easier to understand for the people who don't know about it :)
void Main()
{
Console.WriteLine("before class constructor");
var test = new TestClass();
Console.WriteLine("after class constructor");
var attrs = Attribute.GetCustomAttributes(test.GetType()).Dump();
foreach(var attr in attrs)
if (attr is TestClassAttribute)
Console.WriteLine(attr.ToString());
}
public class TestClassAttribute : Attribute
{
public TestClassAttribute()
{
DefaultDescription = "hello";
Console.WriteLine("I am here. I'm the attribute constructor!");
}
public String CustomDescription {get;set;}
public String DefaultDescription{get;set;}
public override String ToString()
{
return String.Format("Custom: {0}; Default: {1}", CustomDescription, DefaultDescription);
}
}
[Serializable]
[TestClass(CustomDescription="custm")]
public class TestClass
{
public int Foo {get;set;}
}
The console result of this method is:
before class constructor
after class constructor
I am here. I'm the attribute constructor!
Custom: custm; Default: hello
And the Attribute.GetCustomAttributes(test.GetType()) returns this array:
(the table shows all available columns for all entries.. So no, the Serializable attribute does not have these properties :) )
Got any more questions? Feel free to ask!
UPD:
I've seen you ask a question: why use them?
As an example I'll tell you about the XML-RPC.NET library.
You create your XML-RPC service class, with methods that will represent the xml-rpc methods. The main thing right now is: in XmlRpc the method names can have some special characters, like dots. So, you can have a flexlabs.ProcessTask() xml rpc method.
You would define this class as follows:
[XmlRpcMethod("flexlabs.ProcessTask")]
public int ProcessTask_MyCustomName_BecauseILikeIt();
This allows me to name the method in the way I like it, while still using the public name as it has to be.
Attributes are essentially meta data that can be attached to various pieces of your code. This meta data can then be interogate and affect the behaviour of certain opperations.
Attributes can be applied to almost every aspect of your code. For example, attributes can be associated at the Assembly level, like the AssemblyVersion and AssemblyFileVersion attributes, which govern the version numbers associated with the assembly.
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
Then the Serializable attribute for example can be applied to a type declaration to flag the type as supporting serialization. In fact this attribute has special meaning within the CLR and is actually stored as a special directive directly on the type in the IL, this is optimized to be stored as a bit flag which can be processed much more efficiently, there are a few attributes on this nature, which are known as pseudo custom attributes.
Still other attributes can be applied to methods, properties, fields, enums, return values etc. You can get an idea of the possible targets an attribute can be applied to by looking at this link
http://msdn.microsoft.com/en-us/library/system.attributetargets(VS.90).aspx
Further to this, you can define your own custom attributes which can then be applied to the applicable targets that your attributes are intended for. Then at runtime your code could reflect on the values contained in the custom attributes and take appropriate actions.
For a rather naive example, and this is just for the sake of example :)
You might want to write a persistence engine that will automatically map Classes to tables in your database and map the properties of the Class to table columns. You could start with defining two custom attributes
TableMappingAttribute
ColumnMappingAttribute
Which you can then apply to your classes, as an example we have a Person class
[TableMapping("People")]
public class Person
{
[ColumnMapping("fname")]
public string FirstName {get; set;}
[ColumnMapping("lname")]
public string LastName {get; set;}
}
When this compiles, other than the fact that the compiler emits the additional meta data defined by the custom attributes, little else is impacted. However you can now write a PersistanceManager that can dynamically inspect the attributes of an instance of the Person class and insert the data into the People table, mapping the data in the FirstName property to the fname column and the LastName property to the lname column.
As to your question regarding the instances of the attributes, the instance of the attribute is not created for each instance of your Class. All instances of People will share the same instance of the TableMappingAttribute and ColumnMappingAttributes. In fact, the attribute instances are only created when you actually query for the attributes the first time.
Yes they're instantiated with the parameters you give it.
The attribute does not "access" the class. The attribute is attached to the class' / property's attribute list in the reflection data.
[Serializable]
public class MyFancyClass
{ ... }
// Somewhere Else:
public void function()
{
Type t = typeof(MyFancyClass);
var attributes = t.GetCustomAttributes(true);
if (attributes.Count(p => p is SerializableAttribute) > 0)
{
// This class is serializable, let's do something with it!
}
}
Think of attributes are post-its that are attached to the classes or method definitions (embedded in the assembly metadata).
You can then have a processor/runner/inspector module that accepts these types by reflecting, looks for these post-its and handles them differently. This is called declarative programming. You declare some behavior instead of writing code for them in the type.
Serializable attribute on a type declares that it is built to be serialized. The XmlSerializer can then accept an object of this class and do the needful. You mark the methods that need to be serialized/hidden with the right post-its.
another example would the NUnit. The NUnit runner looks at the [TestFixture] attributes all classes defined in the target assembly to identify test classes. It then looks for methods marked with [Test] attribute to identify the tests, which it then runs and displays the results.
You may want to run through this tutorial at MSDN which has most of your questions answered along with an example at the end. Although they could have extracted a method called
Audit(Type anyType); instead of duplicating that code. The example 'prints information' by inspecting attributes.. but you could do anything in the same vein.
If you take an eye out this downloadable open source code LINQ to Active Directory (CodePlex), you might find interesting the mechanism of the Attributes.cs file where Bart De Smet has written all of his attributes classes definitions. I have learned attributes there.
In short, you may specialize the Attribute class and code some specialized properties for your needs.
public class MyOwnAttributeClass : Attribute {
public MyOwnAttributeClass() {
}
public MyOwnAttributeClass(string myName) {
MyName = myName;
}
public string MyName { get; set; }
}
and then, you may use it wherever MyOwnAttributeClass gets useful. It might either be over a class definition or a property definition.
[MyOwnAttributeClass("MyCustomerName")]
public class Customer {
[MyOwnAttributeClass("MyCustomerNameProperty")]
public string CustomerName { get; set; }
}
Then, you can get it through reflection like so:
Attribute[] attributes = typeof(Customer).GetCustomAttribute(typeof(MyOwnAttributeClass));
Consider that the attribute you put between square brackets is always the constructor of your attribute. So, if you want to have a parameterized attribute, you need to code your constructor as such.
This code is provided as is, and may not compile. Its purpose is to give you an idea on how it works.
Indeed, you generally want to have a different attribute class for a class than for a property.
Hope this helps!
Not much time to give you a fuller answer, but you can find the Attributes that have been applied to a value using Reflection. As for creating them, you inherit from the Attribute Class and work from there - and the values that you supply with an attribute are passed to the Attribute class's constructor.
It's been a while, as you might be able to tell...
Martin