Frage

Im Moment habe ich diese Art von Code:

private void FillObject(Object MainObject, Foo Arg1, Bar Arg2)
{
    if (MainObject is SomeClassType1)
    {
        SomeClassType1 HelpObject = (SomeClassType1)MainObject;
        HelpObject.Property1 = Arg1;
        HelpObject.Property2 = Arg2;
    }
    else if (MainObject is SomeClassType2)
    {
        SomeClassType2 HelpObject = (SomeClassType2)MainObject;
        HelpObject.Property1 = Arg1;
        HelpObject.Property2 = Arg2;
    }
}

Unter der Annahme, dass SomeClassType1 und SomeClassType2 den gleichen Satz von Eigenschaften, die ich zugewiesen werden soll (obwohl sie in anderen abweichen können), ist es möglich, dynamisch MainObject in dem entsprechenden Typen zu werfen und dann den Wert zuweisen, ohne den Code zu duplizieren ? Dies ist, was ich möchte am Ende sehen:

private void FillObject(Object MainObject, Foo Arg1, Bar Arg2)
{
    Type DynamicType = null;

    if (MainObject is SomeClassType1)
    {
        DynamicType = typeof(SomeClassType1);
    }
    else if (MainObject is SomeClassType2)
    {
        DynamicType = typeof(SomeClassType2);
    }

    DynamicType HelpObject = (DynamicType)MainObject;
    HelpObject.Property1 = Arg1;
    HelpObject.Property2 = Arg2;
}

Und natürlich C # beschwert sich über nicht in der Lage zu sein DynamicType zu finden:

  

Der Typ oder Namespace-Name ‚DynamicType‘ konnte nicht gefunden werden (möglicherweise fehlt eine using-Direktive oder ein Assemblyverweis?)

Ist so etwas möglich in C # 2.0? Wenn es mehr chaotisch als mein aktueller Code, als ich keinen Sinn darin, dies zu tun, aber ich bin sehr daran interessiert zu erfahren. Dank!

EDIT: Nur um zu klären, ich vollkommen verstehen, dass eine Schnittstelle implementiert, ist die am besten geeignete und wahrscheinlich richtige Lösung. Das heißt, ich bin mehr daran interessiert zu sehen, wie ich es ohne die Implementierung einer Schnittstelle tun könnte. Vielen Dank für die tollen Antworten!

War es hilfreich?

Lösung

Es sieht aus wie beide Typen die gleichen zwei Eigenschaften implementieren Sie sich interessieren. In diesem Fall wollen, was Sie tun, um eine Schnittstelle für diese Eigenschaften definieren:

public interface IMyInterface
{
   public Foo Property1 {get; set;}
   public Bar Property2 {get;set;}
}

Dann stellen Sie sicher, dass jede Ihrer Klassen den Compiler sagen, dass sie die neue Schnittstelle implementieren. Schließlich eine generische Methode mit einem Typ-Argumente verwenden, die zu diesem interace beschränkt ist:

private void FillObject<T>(T MainObject, Foo Arg1, Bar Arg2) 
    where T : IMyInterface
{
    MainObject.Property1 = Arg1;
    MainObject.Property2 = Arg2;
}

Beachten Sie, dass auch mit dem zusätzlichen Code, um die Schnittstelle zu erklären, noch diese Schnipsel kürzer am Ende als einer der Schnipsel Sie in der Frage gestellt, und dieser Code viel einfacher ist, zu verlängern, wenn die Anzahl der Typen Sie erhöht sich kümmern .

Andere Tipps

Im Wesentlichen, was Sie hier tun ist eine switch-Anweisung zu schreiben, basierend auf der Art fo das Objekt. Es gibt keinen von Natur aus gut Weg, um diese andere als Ihr erstes Beispiel zu tun (was bestenfalls langweilig ist).

schrieb ich einen kleinen Rahmen auf Typen zum Schalten, die die Syntax etwas prägnanter machen. Es ermöglicht Ihnen, Code wie den folgenden zu schreiben.

TypeSwitch.Do(
    sender,
    TypeSwitch.Case<Button>(
        () => textBox1.Text = "Hit a Button"),
    TypeSwitch.Case<CheckBox>(
        x => textBox1.Text = "Checkbox is " + x.Checked),
    TypeSwitch.Default(
        () => textBox1.Text = "Not sure what is hovered over"));

Blog: http: // blogs .msdn.com / JaredPar / Archiv / 2008/05/16 / Schalt-on-types.aspx

Werden Sie in der Lage sein, Änderungen an SomeClassType1 zu machen, SomeClassType2 etc? Wenn ja, dann werde ich vorschlagen, dass Sie eine Schnittstelle mit Ihren gemeinsamen Eigenschaften erstellen und dann Typumwandlung an diese Schnittstelle innerhalb FillObject() die Eigenschaften eingestellt wird.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace SO566510
{
    interface IMyProperties
    {
        int Property1 { get; set; }
        int Property2 { get; set; }
    }

    class SomeClassType1 : IMyProperties
    {
        public int Property1 { get; set; }
        public int Property2 { get; set; }
    }

    class SomeClassType2 : IMyProperties
    {
        public int Property1 { get; set; }
        public int Property2 { get; set; }
    }
    class Program
    {
        static void Main(string[] args)
        {
            var obj1 = new SomeClassType1();
            var obj2 = new SomeClassType2();

            FillObject(obj1, 10, 20);
            FillObject(obj2, 30, 40);

        }

        private static void FillObject(IMyProperties objWithMyProperties
                                   , int arg1, int arg2)
        {
            objWithMyProperties.Property1 = arg1;
            objWithMyProperties.Property2 = arg2;
        }
    }
}
private void FillObject(Object MainObject, Foo Arg1, Bar Arg2)
{
    Type t = MainObject.GetType();

    t.GetProperty("Property1").SetValue(MainObject, Arg1, null);
    t.GetProperty("Property2").SetValue(MainObject, Arg2, null);
}

Einige Ideen:

  1. Habe beiden Typen vom gleichen Typ erben, dass die gemeinsame Eigenschaften
  2. Haben beide Typen die gleiche Schnittstelle implementieren, die die gemeinsamen Eigenschaften
  3. haben
  4. Verwenden Reflexion der Eigenschaften einzustellen, anstatt sie direkt einstellen (das ist wahrscheinlich mehr hässlich als es wert ist)
  5. Verwenden Sie den neuen dynamische Feature , ich habe nicht versucht, aber es sieht aus wie Ihr Problem beheben könnte

Statt zu werfen versuchen, vielleicht versuchen könnten Sie die Eigenschaften mithilfe von Reflektion zu setzen.

Ich bin Gießen dynamisch Objekte Spiegelung in einem ASP.NET MVC-App. Grundsätzlich I die Eigenschaften einer Klasse aufzuzählen, findet den entsprechenden Wert in dem Datenspeicher und dynamisch den Wert gegossen und Zuweisen zu der Objektinstanz. Sehen Sie mein Blog-Post Dynamische Casting mit .NET

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top