21

I need to create a heterogeneous List of objects (custom classes). My first thought was to create a List<ISomeMarkerInterface> but I quickly learned that this is not what I want. My next thought was List<dynamic> and this didn't seem to be a bad idea. However, I was doing some research and came across this article about boxing and unboxing and in the example, they're doing basically what I want using List<Object>.

Aside from the fact that dynamic will be evaluated at runtime and Object at compile-time, what is the difference between List<dynamic> and List<Object>? Aren't they essentially the same thing?


Lftp allows specifying passwords for both ftp and sftp and does not require public keys at all. Your sh sync script may look like this:

#!/bin/sh
# Define folders
THEFOLDER='/mnt/my/folder'
# List files
THEFILES=`ls -p $THEFOLDER | grep -v "/"`

for file in $THEFILES
do
  echo "Processing $file"
  lftp -u login,password -e "put $THEFOLDER/$file;quit"  theftp/sub/folder
done
4

2 に答える 2

25

C# には、object、var、および dynamic の 3 つの「一般的な」型があります (ただし、すべてが実際の型というわけではありません)。

物体

他の型と同様に、1 つの特別なルールを持つ実際の型: 型が継承されない場合は、objectから継承されます。このことから、すべての型はobjectから直接的または間接的に継承することになります。

強調: object は typeです。オブジェクトはobject型にすることができ、その型には ToString() などのメソッドがあります。すべてがobjectから継承されるため、すべてをobjectにアップキャストできます。オブジェクト参照にオブジェクトを代入すると、 ElephantがAnimalから継承するAnimal参照にElephantタイプのオブジェクトを代入するときと同じように、アップキャストが行われます。

SomeType x = new SomeType();
object obj = x;
obj.DoSomething();
  • objはコンパイル時にobject型として扱われ、実行時にobject型になります (これは実際の型であるため論理的です - objはobjectとして宣言されているため、その型のみにすることができます)
  • obj.DoSomething()は、SomeType にこのメソッドがあるかどうかに関係なく、 objectにこのメソッドがないため、コンパイル時エラーが発生します。

ヴァール

これは実際の型ではありません。単に「コンパイラ、割り当ての右側に基づいて型を見つけてください」の省略形です。

SomeType x = new SomeType();
var obj = x;
obj.DoSomething();
  • objはコンパイル時にSomeType型として扱われ、"var" の代わりに "SomeType" を記述したかのように、実行時にSomeType型になります。
  • SomeTypeにメソッドDoSomething()がある場合、このコードは機能します
  • SomeTypeにメソッドがない場合、コードはコンパイル時エラーを引き起こします

動的

これは、変数のコンパイル時の型チェックを無効にするようにコンパイラに指示する型です。オブジェクトは、コンパイル時および実行時に動的な型を持つものとして扱われます。

SomeType x = new SomeType();
dynamic obj = x;
obj.DoSomething();
  • obj は、コンパイルおよび実行時に動的タイプです
  • SomeTypeにメソッドDoSomething()がある場合、このコードは機能します
  • SomeTypeにメソッドがない場合、コードはコンパイルされますが、実行時に例外がスローされます
  • 不注意に使用すると、 dynamicは非常に簡単に例外を引き起こす可能性があることに注意してください。

    public void f(dynamic x)
    { 
        x.DoSomething();
    }
    

xがDoSomethingメソッドを持たない型の場合、これは例外をスローしますが、それを呼び出して、コンパイル時エラーなしでパラメーターとして任意のオブジェクトを渡すことは引き続き可能であり、それ自体のみを示すエラーが発生します。実行時、そしておそらく特定の状況でのみ - 潜在的なバグ。したがって、クラスの任意の種類のパブリック インターフェイスで動的を使用する場合は、リフレクションを使用して実行時に常に手動で型チェックを行うか、例外を慎重に処理するか、最初から型チェックを行わないようにする必要があります。

注: もちろん、参照されているオブジェクトの型が変わることはありません。objはobjectかもしれませんが、それが参照するxはまだSomeTypeです。

于 2012-04-30T08:14:41.257 に答える
2

違いは、オブジェクトを使用してオブジェクトのメンバーにアクセスしようとすると、コンパイル時エラーになることです (オブジェクトにはこのメンバーがないため)。機能するには、型が何であるかを知り、それをキャストする必要があります。

dynamic を使用すると、任意のメンバーにアクセスできます。コンパイル時エラーは発生しません。メンバーが実行時に存在しない場合は、実行時エラーになります。これは、たとえば、異種オブジェクトがすべて同じメンバーを持っていることがわかっている場合の方法です。

ただし、この場合、別のより明確な解決策があります。このメンバーを使用してインターフェイスを定義し、すべての異種オブジェクトにそれを実装させ、リストをList<IYourInterface>.

動的な型解決のために、動的なパフォーマンスがわずかに低下する可能性があることに注意してください。

于 2012-04-30T07:33:26.330 に答える