2

ActionBase、ActionA、ActionB、およびActionCは、(データベースからの)エンティティです。ActionA、ActionB、およびActionCは、ActionBaseの派生タイプです。

ActionBとActionCは、SpecialPropertyを使用してISpecialActionを実装します。

元 :

public interface ISpecialAction
{
    Guid SpecialProperty { get; }
}

public partial class ActionBase
{
    public objectX OnePropertyBase { get; set; }
}

public partial class ActionA : ActionBase
{
    public objectY OnePropertyA { get; set; }
}

public partial class ActionB:ActionBase,ISpecialAction 
{
    public objectZ OnePropertyB { get; set; }

    public Guid SpecialProperty
    {
        get
        {
            return OnePropertyB.ID;
        }
    }
}

public partial class ActionC : ActionBase ,ISpecialAction 
{
    public objectW OnePropertyC { get; set; }

    public Guid SpecialProperty
    {
        get
        {
            return OnePropertyC.ID;
        }
    }
}

私の問題は、SpecialPropertyがオブジェクトの他のプロパティ(ActionBまたはActionC)から構築され、(ISpecialActionへの)キャストが行われると、OtherPropertyとOtherProperty2がnullになることです。私は試した :

GetActionBase().ToList().Where(x=>x is ISpecialAction && ((dynamic) x).SpecialProperty== p_SpecialProperty);
GetActionBase().ToList().Where(x=>x is ISpecialAction && ((ISpecialAction) x).SpecialProperty== p_SpecialProperty);
GetActionBase().ToList().OfType<ISpecialAction>().Where(x => x.SpecialProperty== p_SpecialProperty).Cast<ActionBase>();
return GetActionOnGoing().ToList().OfType<ICityAction>().Cast<ActionBase>().Where(x => ((dynamic)x).CityId == p_CityId);

備考:OfType<>エンティティへのLinqのインターフェイスでは機能しませんが、オブジェクトへのLinqでは問題ありません

オブジェクトのタイプを知らずにプロパティインターフェイスにアクセスするにはどうすればよいですか?

4

3 に答える 3

0

私があなたの質問を正確に理解しているかどうかはわかりませんが、次のような中間インターフェースを使用してみてください。

public interface ISpecialActionB : ISpecialAction
{
    objectZ OnePropertyB { get; set; }
}

public class ActionB : ActionBase, ISpecialActionB
{
    //same stuff
}

代わりにそれにキャストします。

var b = new ActionB{OnePropertyB = new Whatever()};

var bAsSpecial = b as ISpecialActionB;

var whatever =  b.OnePropertyB; // should not be null
于 2012-12-12T14:13:00.333 に答える
0

私は何かを逃したかもしれませんが、これはあなたが提供したコードで大丈夫です:

public class objectX
{

}
public class objectY
{

}
public class objectZ
{
    public Guid ID { get { return Guid.NewGuid();} }
}
public class objectW
{
    public Guid ID { get { return new Guid(); } }
}

class Program
{
    private static Guid p_SpecialProperty;
    static void Main(string[] args)
    {
        var result = GetActionBase().ToList().Where(x => x is ISpecialAction && ((dynamic)x).SpecialProperty == p_SpecialProperty).FirstOrDefault();
        var result1 = GetActionBase().ToList().Where(x => x is ISpecialAction && ((ISpecialAction)x).SpecialProperty == p_SpecialProperty).FirstOrDefault();
        var result2 = GetActionBase().ToList().OfType<ISpecialAction>().Where(x => x.SpecialProperty == p_SpecialProperty).Cast<ActionBase>().FirstOrDefault();
                }

    private static IEnumerable<ActionBase> GetActionBase()
    {
        return new List<ActionBase> {new ActionA{OnePropertyA= new objectY()}, new ActionB{OnePropertyB=new objectZ()},new ActionC{OnePropertyC=new objectW()} };
    }
}
于 2012-12-12T14:41:54.997 に答える
0

いいよ。

あなたの例は問題なく非常にうまく動作するので、私は別の方法で検索しました:AutoMapper。

l_List.Actions = Mapper.Map<List<ActionBase>, Action[]>(l_ActionManagement.GetActionBySpecialId(l_Special.ID).ToList());

問題はインターフェイスやLinqクエリではありませんでしたが、オートマッパーには空のコンストラクターが必要であり、このコンストラクターでは、SpecialPropertyを計算するためにOnePropertyBとOnePropertyCを初期化する必要があります。

ありがとう

于 2012-12-12T16:11:26.113 に答える