How can I get the name of the original property name which is passed as a parameter to a method?
class TestA
{
public string Foo { get; set; }
public TestA()
{
Foo = "Bar";
TestB.RegisterString(Foo);
}
}
class TestB
{
public static void RegisterString(string inputString)
{
// Here I want to receive the property name that was used
// to assign the parameter input string
// I want to get the property name "Foo"
}
}
You can add an argument with the nameof keyword. Not sure why you would want that anyway:
TestB.RegisterString(Foo, nameof(Foo));
This will pass in "Foo" as the second argument. There is no way to automate this, so you don't need to call nameof yourself, which makes doing this quite useless.
If you would call this from the Foo property, you could use the CallerMemberNameAttribute, which will put in the caller's name. The compiler will set the correct value, so you don't have to supply this yourself in the calling method.
public static void RegisterString( string inputString
, [CallerMemberName] string caller = null
)
{
// use caller here
}
That makes more sense to me.
Related
Background: a class constructor can have parameters whose names are the same as its properties, and resolve the assignment using the this keyword. Simplified example:
public MyClass(string Thing1, string Thing2)
{
this.Thing1 = Thing1;
this.Thing2 = Thing2;
}
What about object initializers? I want to instantiate an object, setting properties Amount and Percentage from parameters of the same name passed to the current method.
How can I qualify Amount and Percentage to distinguish the object properties from the method parameters?
I guess you're not using object initializer, instead you just have the braces with parameter assigned to itself.. With object initializers, it just works.
Here is the minimal repro:
private static void Dosomething(string Name)
{
{ Name = Name };//Assignment made to same variable error
var test = new TestClass{ Name = Name };//Works fine
}
class TestClass
{
public string Name { get; set; }
}
I need to get the property name of a static property dynamically called as a parameter.
Here is my Portable Class Library code:
public partial class Test
{
public Test()
{
string staticPropName = Test.GetPropName(Test.Row); // result must be "Row" without additional string
System.Diagnostics.Debug.WriteLine("propName=" + staticPropName);
}
public static int Row { get; set; }
public static string GetPropName(object Property)
{
return "Row"; // using reflection
}
}
I don't know the name of the property and I don't want to define it with an additional string.
You can't do that - when function is called it gets value of the property and have no idea where this value come from. Your sample is equivalent of
string staticPropName = Test.GetPropName(42);
which nobody would expect to return name.
You can try to require Expression as argument so you can actually inspect what method get called with like following staring point (https://stackoverflow.com/questions/1011109/how-do-you-get-the-name-of-the-property):
public static string GetPropName<TResult>(Expression<Func<TResult>> expression)
{
MemberExpression body = (MemberExpression)expression.Body;
return body.Member.Name;
}
string staticPropName = Test.GetPropName(()=> Test.Prop);
Note that you need checks to make sure expression is just one you expect and not something like () => Test + 42 or more complex one and report nice error.
Is it acceptable practice to pass an object into a method, then return the same object rather than creating a new object inside of the method itself?
As an example: if have an entity class as follows:
class UserDetails {
int UserID { get; set; }
string UserName { get; set; }
string UserAge { get; set; }
}
And then I pass an instance of this class to a method, as follows:
UserDetails UserInfo = new UserDetails();
UserInfo = Get_Details(UserInfo);
Is it reasonable for the method to do the following?
public UserDetails Get_Details(UserDetails user) {
// SQL Operations...
user.age = 32;
return user;
}
IMO, there is no need to return the object. Since it is passed to the method by reference, the caller already has a reference to the same object (with the updated values after the method completes).
On the other hand, what can be useful in some situations is a fluent-interface, where instance-methods of a class return the instance again, e.g:
class X
{
public X DoThis(int number)
{
// do something
return this;
}
public X DoThat(string name)
{
// do something else
return this;
}
}
This allows to write very readable code, such as:
var x = new X().DoThis(23).DoThat("asdf");
This can be useful with the builder pattern (when you want to build a complex object step by step).
As a very bad example:
class FooBuilder {
FooBuilder WithAge(int age);
FooBuilder WithUrl(Url url);
Foo ToFoo();
}
new FooBuilder().WithAge(12).WithUrl(new Url("http://www.happybirthday.com/").ToFoo();
In your particular case, I'd prefer to initialize everything in one go with the initializer syntax.
new User { Age = 45, UserName = "Bob", Id = 101 };
There is nothing horribly wrong with this but a couple of observations;
You are setting details inside of a method called get perhaps load is more appropriate.
If you are only passing in UserDetails because you want the id for your then the parameter should just be id instead. This keeps the interface cohesive.
It is generally considered bad form to modify a parameter object within a method, i.e., mutation principle.
Doing it like that is rather pointless, as the assignment that you do doesn't change anything.
Calling it like this:
UserInfo = Get_Details(UserInfo);
gives the same result as calling it and ignoring the return value:
Get_Details(UserInfo);
Returning the reference may only be confusing, leading someone to believe that the method returns a new instance, as that would be the only logical reason to return a reference.
It would make more sense to have that method in the class, so that you call it as:
UserInfo.Get_Details();
If your method is supposed to initialise the object, you would rather put the code it the constructor than calling it after creating the instance:
class UserDetails {
int UserID { get; set; }
string UserName { get; set; }
string UserAge { get; set; }
public UserDetails() {
Get_Details(this);
}
}
Then you just create the instance, and the constructor loads the data:
UserDetails UserInfo = new UserDetails();
This is a possible approach and when you have only ONE item to work one, the best, too. You might also consider to use ref, which creates a reference to the passed parameter
public void Get_Details(ref UserDetails user)
{
// SQL Operations. . .
user.age= 32;
}
this way, you don't pass a copy, but reference the object you passed in. But this can become quite obscure and is unnecessary in your case. See here for an insight.
You can fill your entity in its constructor method or another method inside entity class. It will be ready to use when created.
public class SomeClass
{
public string Field_1;
public int Field_2;
public SomeClass(int ID)
{
// Sql operations by ID or another value
// set fields
}
public AnotherMethod(int ID)
{
// Sql operations by ID or another value
// set fields
}
}
You might do well to look up the concepts of the Repository Pattern and OOD. In general, I prefer projections or fully loaded entities.
public UserDetailsProjection GetDetailsByUserId(Guid userID)
{
// Code goes here
return user;
}
Note: ref is not required, because all objects are passed by reference.
Is there a way to access member by a string (which is the name)?
E.g. if static code is:
classA.x = someFunction(classB.y);
but I only have two strings:
string x = "x";
string y = "y";
I know in JavaScript you can simply do:
classA[x] = someFunction(classB[y]);
But how to do it in C#?
Also, is it possible to define name by string?
For example:
string x = "xxx";
class{
bool x {get;set} => means bool xxx {get;set}, since x is a string
}
UPDATE, to tvanfosson, I cannot get it working, it is:
public class classA
{
public string A { get; set; }
}
public class classB
{
public int B { get; set; }
}
var propertyB = classB.GetType().GetProperty("B");
var propertyA = classA.GetType().GetProperty("A");
propertyA.SetValue( classA, someFunction( propertyB.GetValue(classB, null) as string ), null );
You need to use reflection.
var propertyB = classB.GetType().GetProperty(y);
var propertyA = classA.GetType().GetProperty(x);
propertyA.SetValue( classA, someFunction( propertyB.GetValue(classB,null) as Foo ), null );
where Foo is the type of the parameter that someFunction requires. Note that if someFunction takes an object you don't need the cast. If the type is a value type then you'll need to use (Foo)propertyB.GetValue(classB,null) to cast it instead.
I'm assuming that we are working with properties, not fields. If that's not the case then you can change to use the methods for fields instead of properties, but you probably should switch to using properties instead as fields shouldn't typically be public.
If the types aren't compatible, i.e., someFunction doesn't return the type of A's property or it's not assignable, then you'll need to do a conversion to the proper type. Similarly if the type of B isn't compatible with the parameter of the function, you'll need to do the same thing.
propetyA.SetValue( classA, someFunction(Convert.ToInt32( propertyB.GetValue(classB,null))).ToString() );
Hi is it possible to specify a method that is the default method for a C# class? I am writing a short class to output embed code for a video, here is the basic idea:
public class EmbeddedVideo
{
public string VideoPath { get; set; }
public string ImagePath { get; set; }
public string EmbedCode()
{
return "...";
}
}
Now if I were to say:
Response.Write(new EmbeddedVideo());
It would output the result of the GetType() method. How can I specify that I would like the EmbedCode() method to be the default in this context?
Override ToString(), which gets called in many scenarios where string conversion takes place:
public override string ToString()
{
return EmbedCode();
}
The "default" you're referring to is the default implementation of Object.ToString(), which simply happens to return the type name:
The default implementation returns the fully qualified name of the type of the Object.
It sounds like by "default method" you mean "method which controls how instances of the type are displayed in methods like Write." If so what you want to do is override the ToString method.
public override string ToString() {
return EmbedCode();
}