英文:
Is possible to create an extension method that will obtain both the property name and its value
问题
我有一个名为MyObj
的类,其中有一个属性Amount
。
我可以创建一个扩展方法,以以下方式调用它吗:
myObj.Amount.DoSomething();
在DoSomething()
方法内,我需要能够获取属性的名称,即Amount
,以及其实际值。
这是否可能?
英文:
Say I have a class MyObj
with a property Amount.
Can I create an extension method that will be called like this:
myObj.Amount.DoSomething();
Inside DoSomething()
I need to be able to get both the property name, which is Amount
, and its actual value.
Is this possible?
答案1
得分: 1
这个问题的答案是,可以使用[CallerArgumentExpression("value")]
属性来实现这一点。
以下是您说您需要的代码示例:
void Main()
{
var myObj = new MyObj() { Amount = 42 };
myObj.Amount.DoSomething();
}
public class MyObj
{
public decimal Amount { get; init; }
}
public static class Extensions
{
public static void DoSomething(this decimal value, [CallerArgumentExpression("value")] string caller = "?")
{
Console.WriteLine($"caller: {caller}");
Console.WriteLine($"value: {value}");
}
}
运行此代码会输出:
caller: myObj.Amount
value: 42
您需要解析出Amount
字符串。
不幸的是,这段代码很容易变得难以处理,并且可能会被滥用。
看看对MyObj
的这个扩展:
public class MyObj
{
public decimal Amount { get; init; }
public decimal Amount2() => this.Amount;
public decimal Amount3(decimal factor) => this.Amount * factor;
}
现在,我可以编写这段代码:
var myObj = new MyObj() { Amount = 42 };
myObj.Amount.DoSomething();
myObj.Amount2().DoSomething();
myObj.Amount3(2).DoSomething();
decimal x = 43;
x.DoSomething();
44m.DoSomething();
myObj.Amount3(x).DoSomething();
0m.DoSomething("Ha ha");
这将给出以下结果:
caller: myObj.Amount
value: 42
caller: myObj.Amount2()
value: 42
caller: myObj.Amount3(2)
value: 84
caller: x
value: 43
caller: 44m
value: 44
caller: myObj.Amount3(x)
value: 1806
caller: Ha ha
value: 0
您确实需要准备好解析返回的各种结构,还需要知道何时您的代码正在调用扩展方法,以及何时恶意调用代码试图欺骗其身份。
英文:
It turns out that there is a way to do it using the [CallerArgumentExpression("value")]
attribute
Here's an example of the code you're saying you need:
void Main()
{
var myObj = new MyObj() { Amount = 42 };
myObj.Amount.DoSomething();
}
public class MyObj
{
public decimal Amount { get; init; }
}
public static class Extensions
{
public static void DoSomething(this decimal value, [CallerArgumentExpression("value")] string caller = "?")
{
Console.WriteLine($"caller: {caller}");
Console.WriteLine($"value: {value}");
}
}
When run this gives:
caller: myObj.Amount
value: 42
You need to parse out the Amount
string.
Unfortunately, this code can easily become difficult to work with and it can be abused.
Look at this extension to MyObj
:
public class MyObj
{
public decimal Amount { get; init; }
public decimal Amount2() => this.Amount;
public decimal Amount3(decimal factor) => this.Amount * factor;
}
Now I can write this code:
var myObj = new MyObj() { Amount = 42 };
myObj.Amount.DoSomething();
myObj.Amount2().DoSomething();
myObj.Amount3(2).DoSomething();
decimal x = 43;
x.DoSomething();
44m.DoSomething();
myObj.Amount3(x).DoSomething();
0m.DoSomething("Ha ha");
That gives me:
caller: myObj.Amount
value: 42
caller: myObj.Amount2()
value: 42
caller: myObj.Amount3(2)
value: 84
caller: x
value: 43
caller: 44m
value: 44
caller: myObj.Amount3(x)
value: 1806
caller: Ha ha
value: 0
You will really need to be prepared to parse the various structures returned and you will need to know when your code is calling the extension method and you'll need to know when nefarious calling code is trying to spoof who it is.
答案2
得分: -2
是的,当然,看起来您想要将内部类添加到您的类中。
class Test
{
void Main()
{
MyObj obj = new MyObj();
obj.Amount.DoSomething();
}
}
class MyObj
{
public Amount Amount;
}
class Amount
{
public void DoSomething()
{
}
}
据我所知,您不能像您展示的那样串联一个函数,但您也可以将一个 Func<>
添加为变量。
至于返回字符串和整数,有多种方法可以做到这一点:您可以返回一个 JSON 字符串,一个元组或只需创建自己的类来返回。
英文:
Yes of course, it looks like you want to add an inner class to your class.
class Test
{
void Main()
{
MyObj obj = new MyObj();
obj.Amount.DoSomething();
}
}
class MyObj
{
public Amount Amount;
}
class Amount
{
public void DoSomething()
{
}
}
As far as I know, you cannot string along a function like you showed but you can also add a Func<> as a variable.
As for returning a string and int, there are multiple ways to do that:
you can return a JSON string, a Tuple or just create your own class to return.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论