我不知道如何更好地制定標題。我看到很多標題相似的帖子,但它們討論的內容完全不同。
所以我們開始了。實際的實地情況很復雜,但我會嘗試發布一個絕對簡約的示例來描述它。
假設我們有一個名為 的類Animal:
class Animal
{
public void Run()
{
try
{
//try running
}
catch(Exception e)
{
MessageBox.Show(this.SomeCleverWayOfGettingPropertyName() " failed to run");
}
}
}
現在我Animal在另一個類中定義了幾個型別的屬性:
class Zoo
{
public Animal Zebra {get; set;}
public Animal Lion {get; set;}
public Animal Rhino {get; set;}
public void RunAll()
{
Zebra.Run();
Lion.Run();
Rhino.Run();
}
}
我應該寫什么SomeCleverWayOfGettingPropertyName()來讓它顯示動物的名稱(即宣告的屬性的名稱),例如“斑馬未能運行”。
正如我所說,實際情況更復雜,所以請避免回答諸如“為什么不重新設計整個代碼庫,而是嘗試 X”之類的答案。我希望能找到一些東西 System.Reflection來找出呼叫成員的名字,但我還沒有找到類似的東西。
uj5u.com熱心網友回復:
理想情況下,您會重新考慮您的問題,并可能在跑步之外抓住
根據您的確切需求,運算式可能會起作用.. 然而,這確實是一個糟糕的解決方案,如果您竭盡全力,您不妨在外面趕上,或者只是將成員名稱傳入。
給定的
public class Animal
{
public void Run()
{
Console.WriteLine("Running");
}
}
public static class MemberInfoGetting
{
public static void Run<T>(this Expression<Func<T>> memberExpression) where T : Animal
{
var expressionBody = (MemberExpression)memberExpression.Body;
try
{
var animal = Expression.Lambda<Func<Animal>>(expressionBody).Compile()();
animal.Run();
throw new Exception("bob");
}
catch
{
Console.WriteLine($"{expressionBody.Member.Name} : failed to run");
}
}
}
用法
public static Animal Rhino { get; set; } = new Animal();
public static void Main()
{
MemberInfoGetting.Run(() => Rhino);
}
輸出
Running
Rhino : failed to run
uj5u.com熱心網友回復:
這種方法基本上是不可能的。當你打電話時會發生什么Zebra.Run():
- 運行時呼叫自動生成的
get_Zebra()方法,將 Zebra 的 Animal 實體指標放在堆疊上。 - 運行時呼叫
Animal.Run()實體方法。
關于該實體來自何處的所有變數/屬性資訊在那時幾乎消失了。
現在Animal.Run()不知道它是在來自屬性的實體上被呼叫的,并且不能保證它會被呼叫。它也可以是本地、方法引數或new()ed 實體、來自工廠或集合元素的實體。您必須自己傳遞此資訊。
或者,如果是用于錯誤處理,它可能比您想象的要容易,而無需決議編譯器魔術或昂貴的運算式重構:
在您的例外處理程式中,記錄標識 Animal 實體的相關屬性。結合堆疊跟蹤,這應該為您提供足夠的資訊。
uj5u.com熱心網友回復:
你可以試試這個:
class Animal
{
public void Run([CallerMemberName] string caller = null)
{
try
{
//try running
}
catch(Exception e)
{
MessageBox.Show(caller " failed to run");
}
}
}
uj5u.com熱心網友回復:
合理執行此操作的唯一方法是更改RunAll()以便它監視每個呼叫,以現在修改的運行
class Animal
{
static readonly Random rng = new Random();
public bool Run()
{
if (rng.NextDouble() < 0.5)
{
return false;
}
return true;
}
}
class Zoo
{
...
public void RunAll()
{
try
{
if (!Zebra.Run())
{
throw new Exception(nameof(Zebra));
}
if (!Lion.Run())
{
throw new Exception(nameof(Lion));
}
if (!Rhino.Run())
{
throw new Exception(nameof(Rhino));
}
}
catch (Exception ex)
{
Debug.WriteLine($"{ex.Message} failed to run.");
}
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/323411.html
上一篇:如何在C#.net中創建DTO
