C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[10]: 何かいい方法ありませんか


(過去ログ 128 を表示中)

[トピック内 14 記事 (1 - 14 表示)]  << 0 >>

■76182 / inTopicNo.1)  何かいい方法ありませんか
  
□投稿者/ よぽん (28回)-(2015/06/09(Tue) 10:11:23)

分類:[.NET 全般] 

今こんなかんじでテストプログラム作っています。

Get なんですけど 引数のType すべて対応するのって
すべて調べて対応するのって大変なんですけど

どんなタイプでも対応できる方法ってあるのでしょうか?


  private void button2_Click(object sender, EventArgs e)
  {
   string[] strs = new string[] { "a", "b", "c", "d", "e" };
   Get(strs, 0);

   int[] ints = new int[] { 1, 2, 3, 4, 5 };
   Get(ints, 1);

   List<int> ilst = new List<int>() { 11, 22, 33, 44 };
   Get(ilst, 2);
  }

  private void Get(object obj, int Num)
  {
   string[] strs;

   if(obj.GetType() == typeof(Int32[]))
   {
    strs = new string[((Int32[])obj).Count()];
    for(int inum = 0; inum < strs.Count(); inum++)
    {
     strs[inum] = ((Int32[])obj)[inum].ToString();
    }
   }
   else if(obj.GetType() == typeof(Double[]))
   {
    strs = new string[((Double[])obj).Count()];
    for(int inum = 0; inum < strs.Count(); inum++)
    {
     strs[inum] = ((Int32[])obj)[inum].ToString();
    }
   }
   else if(obj.GetType() == typeof(Boolean[]))
   {
    strs = new string[((Boolean[])obj).Count()];
    for(int inum = 0; inum < strs.Count(); inum++)
    {
     strs[inum] = ((Int32[])obj)[inum].ToString();
    }
   }
   else if(obj.GetType() == typeof(List<int>))
   {
    strs = new string[((List<int>)obj).Count()];
    for(int inum = 0; inum < strs.Count(); inum++)
    {
     strs[inum] = ((List<int>)obj)[inum].ToString();
    }
   }
   else
   {
    strs = new string[((String[])obj).Count()];
    for(int inum = 0; inum < strs.Count(); inum++)
    {
     strs[inum] = ((String[])obj)[inum].ToString();
    }
   }

   〜この後延々とつづきそう〜
  }

引用返信 編集キー/
■76185 / inTopicNo.2)  Re[1]: 何かいい方法ありませんか
□投稿者/ Hongliang (315回)-(2015/06/09(Tue) 10:25:55)
メソッドの意図が分からないので何とも言えません。
そもそもこのGetなるメソッドの目的は何なのか、
第一引数objが想定するのが配列、List<T>まではあるようですが他にあるのか、
第二引数Numとやらは何を意味するのか、
等々。

とりあえず提示されている部分だけを見れば、
private void Get<T>(IEnumerable<T> obj, int Num) {
    string[] strs = obj.Select(_ => _.ToString()).ToArray();
    ...
}
でよさそうですけど。

引用返信 編集キー/
■76186 / inTopicNo.3)  Re[1]: 何かいい方法ありませんか
□投稿者/ 魔界の仮面弁士 (377回)-(2015/06/09(Tue) 10:36:18)
2015/06/09(Tue) 10:37:52 編集(投稿者)

# もろ被ってた…!

No76182 (よぽん さん) に返信
> Get なんですけど 引数のType すべて対応するのって

第二引数の「int Num」は、どのような意味があるのでしょうか?
一切使われていないようなのですが…。


> すべて調べて対応するのって大変なんですけど
> どんなタイプでも対応できる方法ってあるのでしょうか?

何がやりたいのか良く分からなかったのですが、とりあえず下記は如何でしょう。

 private void Get<T>(IEnumerable<T> obj, int Num)
 {
   string[] strs = obj.Select(o => o.ToString()).ToArray();
   // :
 }
引用返信 編集キー/
■76187 / inTopicNo.4)  Re[1]: 何かいい方法ありませんか
□投稿者/ shu (756回)-(2015/06/09(Tue) 10:51:43)
No76182 (よぽん さん) に返信

>   private void Get(object obj, int Num)

Getするなら
voidではない方がよいです。
提示されたものから判断するとstring[]
とかですかね。

Getという名前のメソッドは言語で使用される既存のものと紛らわしいのでやめた方がよいです。
GetListとかの方がよいかと。または何らかの配列とかListから文字列配列への変換と考えた場合、
GetよりはTrans (Translateの一部)などの方が適切かもしれません。


引用返信 編集キー/
■76197 / inTopicNo.5)  Re[2]: 何かいい方法ありませんか
□投稿者/ よぽん (31回)-(2015/06/11(Thu) 15:08:52)
みなさん
遅くなってすみません。

最終的には void ではなくて string の形で返そうかと思っていました。
作りかけのままというかテストをしながらだったので、
このメソッドには意味はありません。すみません。

num は テスト結果をグリッドに表示させるときの どの列に表示させるかの番号です。

主な目的は

Properties に 配列を保存したくって、でも配列保存できないので


大まかですけど

List<int> ilist = new List<int> { 1, 2, 3 }

SetValue にて string[] str = "1", "2", "3" に変換し   ← 質問したところです

さらに 作成元のタイプ List<> を追加して
str = "List<>", "1", "2", "3"

を作成後
 string.Join("|", str) を 戻り値として


Properties.Settings.Default.xxxx = Setvalue("key1", ilist);

で登録しようかと思いました。。

Properties.Settings.Default.xxxx には最終的に "List<>|1|2|3"
となればいいかなと

で、次に object GetValue(string str) 関数で GetValue(Properties.Settings.Default.xxxx);
を実行して

Split で string[] str に分割して str[0] で型を判別して

List<int> ilist = (List<int>)GetValue(string str)

にすればいいのかなと思ったのですが。

もっといい方法があるのでしょうか?
引用返信 編集キー/
■76198 / inTopicNo.6)  Re[3]: 何かいい方法ありませんか
□投稿者/ よぽん (32回)-(2015/06/11(Thu) 15:14:45)
GetType() すると

String[]
int[]
になるんですけど

ちなみに List<> の場合
GetType() すると "List`1" になってしまって。

List<int> , List<string> の判断できないんですね。

引用返信 編集キー/
■76209 / inTopicNo.7)  Re[4]: 何かいい方法ありませんか
□投稿者/ 魔界の仮面弁士 (378回)-(2015/06/11(Thu) 19:35:11)
No76198 (よぽん さん) に返信
> ちなみに List<> の場合
> GetType() すると "List`1" になってしまって。

"`1" は、1 個の型パラメーターを要求するジェネリック型という意味です。
Dictionary<,> の場合は、"Dictionary`2" ですね。


> List<int> , List<string> の判断できないんですね。

できますよ。

Type t1 = typeof(List<int>);
Type t2 = typeof(List<string>);
Type t3 = typeof(List<>);

Type a = t1.GenericTypeArguments.FirstOrDefault();
Type b = t2.GenericTypeArguments.FirstOrDefault();
Type c = t3.GenericTypeArguments.FirstOrDefault();


なお、文字列から List<int> 型を作りたいのであれば、
 Type type = Type.GetType("System.Collections.Generic.List`1[[System.Int32]]", true);
とします。



No76197 (よぽん さん) に返信
> さらに 作成元のタイプ List<> を追加して
> str = "List<>", "1", "2", "3"

型が動的に決まる以上、受け側は object か dynamic しかないですね。

目的に合致しているかはわかりませんが、文字列からの復元であれば、
 string typeName = "System.Int32";
 string text = "11,22,33";

 Type t = Type.GetType(typeName, true);
 string[] values = text.Split(',');

 // 配列に変換する場合
 dynamic[] ary = values.Select(x => Convert.ChangeType(x, t)).ToArray();

 // リストに変換する場合
 List<dynamic> lst = values.Select(x => Convert.ChangeType(x, t)).ToList();
などと書くことはできます。



> Properties に 配列を保存したくって、でも配列保存できないので

Settings.settings ファイルの <Setting Type="型名"> の部分を、
Type="System.Collections.Generic.List&lt;System.Int32&gt;" や
Type="System.Int32[]" などとすれば、List<> や配列を対象とした
設定が作られますが、止めておいたほうが良いでしょう。

http://www.vb-user.net/junk/replySamples/2015.06.11/Array.png
引用返信 編集キー/
■76210 / inTopicNo.8)  Re[5]: 何かいい方法ありませんか
□投稿者/ 魔界の仮面弁士 (379回)-(2015/06/11(Thu) 21:01:57)
No76209 (魔界の仮面弁士) に追記
>>さらに 作成元のタイプ List<> を追加して
>>	str = "List<>", "1", "2", "3"
> 型が動的に決まる以上、受け側は object か dynamic しかないですね。

型の指定が静的でよければ、こういう書き方もできます。


class Program
{
    static void Main()
    {
        string value = "11,22,33";

        int[]         intArray    = ToEnumerable<int>(value).ToArray();
        string[]      strArray    = ToEnumerable<string>(value).ToArray();
        List<int>     intList     = ToEnumerable<int>(value).ToList();
        List<decimal> decimalList = ToEnumerable<decimal>(value).ToList();
    }

    static IEnumerable<T> ToEnumerable<T>(string commaSeparatedValue)
    {
        return commaSeparatedValue.Split(',').Select(x => (T)Convert.ChangeType(x, typeof(T)));
    }
}

引用返信 編集キー/
■76217 / inTopicNo.9)  Re[6]: 何かいい方法ありませんか
□投稿者/ よぽん (33回)-(2015/06/12(Fri) 09:34:18)
ふと、思ったことですみませんけど

int inum; のように
inum を使用することってできるのでしょうか?

たとえば
Type type = Typeof(Int32);
で Type を指定して。
type inum; のようなことをして

そのあとは inum を int の変数として使用することとかできるのでしょうか?

引用返信 編集キー/
■76218 / inTopicNo.10)  Re[7]: 何かいい方法ありませんか
□投稿者/ 魔界の仮面弁士 (380回)-(2015/06/12(Fri) 09:41:45)
No76217 (よぽん さん) に返信
> int inum; のように
> inum を使用することってできるのでしょうか?

dynamic では駄目ですか?


> Type type = Typeof(Int32);
> で Type を指定して。
> type inum; のようなことをして

ジェネリックでは駄目ですか?


> そのあとは inum を int の変数として使用することとかできるのでしょうか?
「型情報」は、基本的にコンパイル時に決定されます。
Type を変数として渡すのであれば、dynamic か object を使うしか無いでしょう。

もしくは、当初の質問のコードのように、Type に応じて処理を分けるとか。
引用返信 編集キー/
■76232 / inTopicNo.11)  Re[8]: 何かいい方法ありませんか
□投稿者/ よぽん (35回)-(2015/06/16(Tue) 11:37:10)
いまだに 試行錯誤です。

private void Get<T>(IEnumerable<T> obj)
{
string[] strs = obj.Select(o => o.ToString()).ToArray();
}

この場合なんですけど呼出側で

int intnum = 10;
Get(intnum);

とすると
「型引数を使い方から推論することはできません。型引数を明示的に指定してください。」
のようなエラーが出ます。List<>か配列しか使えないのでしょうか?

引用返信 編集キー/
■76233 / inTopicNo.12)  Re[9]: 何かいい方法ありませんか
□投稿者/ shu (758回)-(2015/06/16(Tue) 12:15:53)
No76232 (よぽん さん) に返信
> この場合なんですけど呼出側で
>
> int intnum = 10;
> Get(intnum);
>
> とすると
> 「型引数を使い方から推論することはできません。型引数を明示的に指定してください。」
> のようなエラーが出ます。List<>か配列しか使えないのでしょうか?
>
List<>か配列以外でも列挙出来る(IEnumerable<T>にキャスト出来る)のであれば使えますが
intはIEnumerable<T>には出来ないので使えません。

この場合には何をしたいのでしょう?
引用返信 編集キー/
■76239 / inTopicNo.13)  Re[9]: 何かいい方法ありませんか
□投稿者/ 魔界の仮面弁士 (383回)-(2015/06/16(Tue) 20:56:03)
No76232 (よぽん さん) に返信
> int intnum = 10;
> Get(intnum);

メソッドの定義を変えずに呼び出すなら、

  Get(new[] { intnum });

と書くことになるでしょう。

あるいはその逆で、呼び出し側を弄らずに、メソッド側の定義を変えてよいなら、

 private static void Get<T>(params T[] obj)

という書き方ができます。あるいはオーバーロードで対応するとか。
引用返信 編集キー/
■76246 / inTopicNo.14)  Re[10]: 何かいい方法ありませんか
□投稿者/ よぽん (37回)-(2015/06/18(Thu) 14:15:34)
みなさんすみません。

ところどころはわかったのですが、
Dynamic ジェネリックというのが
いろいろ調べてみたのですが
よくわかりませんでした。

使い方がわからないです。

object, dynamic, ジェネリックはただ単に型の違いだけではなさそうですね。


object はある程度理解できるのですが、
Dynamic は数行を1行で表示できるということぐらいしかわかりませんでしたし。
ジェネリックもやっぱり理解できていないと思います。

ネットで調べていても
こういうときはこうすればよいというのを利用して使うことはできるのですけど
結局そういう時だけにしか利用できないです。
簡単に言えばちょっと違うと使えなくなります。

何を調べれば、dynamic や ジェネリック といったものを
使えるようになるのでしょうか?







解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -