可以创建一个扩展方法,该方法可以获取属性名称和其值。

huangapple go评论69阅读模式
英文:

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.

huangapple
  • 本文由 发表于 2023年1月6日 12:33:15
  • 转载请务必保留本文链接:https://go.coder-hub.com/75026951.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定