簡體   English   中英

有沒有辦法從方法返回匿名類型?

[英]Is there a way to return Anonymous Type from method?

我知道我不能寫一個像這樣的方法:

public var MyMethod()
{
   return new{ Property1 = "test", Property2="test"};
}

我可以這樣做:

public object MyMethod()
{
   return new{ Property1 = "test", Property2="test"}
}

但我不想做第二種選擇,因為如果我這樣做,我將不得不使用反射。


為什么我要這樣做:

今天我在我的aspx頁面中有一個方法返回一個數據表作為結果而我無法更改它 ,我試圖將此DataTable轉換為具有我想要使用的屬性的Anonymous方法。 我不想創建一個類只是為了這樣做,因為我需要多次執行相同的查詢,我想創建一個返回匿名類型的方法將是一個很好的意識形態。

將它作為System.Object返回是從方法返回匿名類型的唯一方法。 不幸的是,沒有其他方法可以做到這一點,因為匿名類型是專門為防止它們以這種方式使用而設計的。

你可以做一些技巧,同時返回一個允許你靠近的Object 如果您對此解決方法感興趣請閱讀不能從方法返回匿名類型? 真?

免責聲明:即使我鏈接的文章確實顯示了一種解決方法,但並不意味着這樣做是個好主意。 我強烈建議您在創建常規類型時使用此方法更安全,更容易理解。

或者,您可以在.NET 4.0及更高版本中使用Tuple類:

http://msdn.microsoft.com/en-us/library/system.tuple(v=vs.110).aspx

Tuple<string, string> Create()
{
return Tuple.Create("test1", "test2");
} 

然后你可以訪問這樣的屬性:

var result = Create();
result.Item1;
result.Item2;
public object MyMethod() 
{
    return new
    {
         Property1 = "test",
        Property2 = "test"
     };
}

static void Main(..)
{
    dynamic o = MyMethod();  
    var p1 = o.Property1;
    var p2 = o.Property2;
}

最簡單的解決方案是創建一個類,將值推送到屬性中,然后返回它。 如果匿名類型讓你的生活變得更難,那么你就沒有正確使用它們。

作為替代方案,從C#7開始,我們可以使用ValueTuple 這里有一個小例子:

public (int sum, int count) DoStuff(IEnumerable<int> values) 
{
    var res = (sum: 0, count: 0);
    foreach (var value in values) { res.sum += value; res.count++; }
    return res;
}

並在接收端:

var result = DoStuff(Enumerable.Range(0, 10));
Console.WriteLine($"Sum: {result.Sum}, Count: {result.Count}");

要么:

var (sum, count) = DoStuff(Enumerable.Range(0, 10));
Console.WriteLine($"Sum: {sum}, Count: {count}");

盡管有關於這是否是一個好主意的警告...... dynamic似乎對私有方法起作用。

void Main()
{
    var result = MyMethod();
    Console.WriteLine($"Result: {result.Property1}, {result.Property2}");
}

public dynamic MyMethod()
{
    return new { Property1 = "test1", Property2 = "test2" };
}

您可以在LinqPad中運行此示例 它將輸出:

結果:test1,test2

不,匿名類型不能存在於創建它們的上下文之外,因此不能用作方法返回類型。 您可以將實例作為object返回,但為此目的顯式創建自己的容器類型更好。

我認為Andrew Hare是對的,你必須回歸“對象”。 對於編輯評論,我覺得在OO代碼中處理原始對象可能是“代碼味道”。 在某些情況下,這是正確的做法,但大多數情況下,如果您要返回相關類型,最好定義一個返回的接口,或使用某種基類類型。

對不起,你真的不應該這樣做。 您可以通過反射或通過使用通用幫助程序方法為您返回類型來解決它,但這樣做實際上是違背語言的。 只需聲明類型,就可以清楚地知道發生了什么。

不,沒有支持擴展方法之外的匿名類的范圍。 在方法之外,類是真正的匿名,反射是訪問它的成員的唯一方法。

如果可能,您也可以反轉控制流程:

    public abstract class SafeAnon<TContext>
    {
        public static Anon<T> Create<T>(Func<T> anonFactory)
        {
            return new Anon<T>(anonFactory());
        }

        public abstract void Fire(TContext context);
        public class Anon<T> : SafeAnon<TContext>
        {
            private readonly T _out;

            public delegate void Delayed(TContext context, T anon);

            public Anon(T @out)
            {
                _out = @out;
            }

            public event Delayed UseMe;
            public override void Fire(TContext context)
            {
                UseMe?.Invoke(context, _out);
            }
        }
    }

    public static SafeAnon<SomeContext> Test()
    {
        var sa = SafeAnon<SomeContext>.Create(() => new { AnonStuff = "asdf123" });

        sa.UseMe += (ctx, anon) =>
        {
            ctx.Stuff.Add(anon.AnonStuff);
        };

        return sa;
    }

    public class SomeContext
    {
        public List<string> Stuff = new List<string>();
    }

然后是其他地方:

    static void Main()
    {
        var anonWithoutContext = Test();

        var nowTheresMyContext = new SomeContext();
        anonWithoutContext.Fire(nowTheresMyContext);

        Console.WriteLine(nowTheresMyContext.Stuff[0]);

    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM