SHOJI's Code
 仕事や趣味で書いた各種言語のプログラミングコード(エクセルVBA,PHP,C/C++/C#,JavaScript等)、その他雑記。
2012.04<<12345678910111213141516171819202122232425262728293031>>2012.06
facebookページを作ってみた
かなり更新が滞っている。

最近よくfacebookを使っているが、今回いろいろ遊んでみようと思い、この「SHOJI's Code」のfacebookページを作ってみた。

アドレスは http://www.facebook.com/SHOJIsCode

まずは、この投稿を利用して、ちゃんと TwitterFeed で投稿されるかのテスト。同じく連携している Twitter や mixi ページがどうなるかの確認。

Boolean型の書式化 (C#)
仕事でC#でプログラミングするときに、よく string.Format メソッドなどで文字列を書式化することがよくあるが、論理型(Boolean)は書式化しても "True" か "False" にしか書式化されない。だから string.Format などで、
string.Format("{0}", b ? "1" : "0");

などとせざるを得ない。特に問題にならないケースも多いが、書式文字列をパラメータ化した場合など、できればboolはboolのまま渡して書式設定でどうにかしたい。

アプローチは2つ。

IFormattableインターフェイスを実装するクラスを作り、その ToString で書式化をサポートする。後述の FormattableBooleanクラスでは以下のようになる。
bool b = true;
FormattableBoolean fb = b;
string s = fb.ToString("{0:Y}");


IFormatProviderとICustomFormatterを実装したクラスを作り、string.Format にカスタム書式設定とする。後述のBooleanFormatterクラスでは以下のように使用する。
string s = string.Format(new BooleanFormatter(), "{0}", b);



public class FormattableBoolean : IFormattable
{
bool b;

public FormattableBoolean(object value) {
b = Convert.ToBoolean(value);
}


public override bool Equals(object obj)
{
if (obj is FormattableBoolean) return b.Equals((bool)obj);
return b.Equals(obj);
}

public override int GetHashCode()
{
return b.GetHashCode();
}

public override string ToString()
{
return b.ToString();
}

public static implicit operator bool(FormattableBoolean fb) {
return fb.b;
}
public static implicit operator FormattableBoolean(bool b) {
return new FormattableBoolean(b);
}

public static bool operator true(FormattableBoolean fb) {
return fb.b;
}
public static bool operator false(FormattableBoolean fb) {
return !fb.b;
}

public static bool operator !(FormattableBoolean fb) {
return new FormattableBoolean(!fb.b);
}

public static bool operator &(FormattableBoolean fb1, FormattableBoolean fb2) {
return fb1.b && fb2.b;
}
public static bool operator |(FormattableBoolean fb1, FormattableBoolean fb2) {
return fb1.b || fb2.b;
}


public string ToString(string format, IFormatProvider formatProvider)
{
if (format == null || format==string.Empty) return ToString();

switch (format) {
case "Y": return b ? "YES" : "NO";
case "y": return b ? "yes" : "no";
case "O": return b ? "ON" : "OFF";
case "o": return b ? "on" : "off";
case "0": return b ? "1" : "0";

default:
string[] pair = format.Split(';');
string st = pair.Length>0 ? pair[0] : string.Empty;
string sf = pair.Length>1 ? pair[1] : string.Empty;
return b ? st : sf;
}
}
}

public class BooleanFormatter : IFormatProvider, ICustomFormatter
{
public object GetFormat(Type formatType)
{
return formatType==typeof(ICustomFormatter) ? this : null;
}

public string Format(string format, object arg, IFormatProvider formatProvider)
{
if (arg is bool) arg = new FormattableBoolean(arg);

if (arg is IFormattable) {
return ((IFormattable)arg).ToString(format, formatProvider);
}
else if (arg!=null) {
return arg.ToString();
}

return string.Empty;
}
}

テーマ:プログラミング - ジャンル:コンピュータ
C#でカリー化 (C#)
以前、JavaScriptでカリー化の記事を書いたが、今回はC#

自分の書いたプログラムなどを整理していたら、テスト的に作ったものであろうカリー化のコードを発見。おそらく先のJavaScriptのカリー化を書いた頃のものであろうと思うが、完成しておらず、途中までだった。
あの頃はC#も始めたばかりで書ききれなかったのだろうと思うが、今なら書けそうなので書いてみた。

それが、これ。結構すっきり書けた。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Reflection;
using System.Reflection.Emit;

namespace CurryTest
{
public static class CurryExtension {

public static Delegate Curry(this Delegate targetMethod) {
MethodInfo method = targetMethod.Method;
ParameterInfo[] argsInfo = method.GetParameters();

ParameterExpression[] args = (from pi in argsInfo select Expression.Parameter(pi.ParameterType, pi.Name)).ToArray();

ConstantExpression instance = Expression.Constant(targetMethod.Target);
MethodCallExpression targetCaller = Expression.Call(instance, method, args);

LambdaExpression retFunc = Expression.Lambda(targetCaller, args.Skip(1).ToArray());

LambdaExpression curry = Expression.Lambda(retFunc, new ParameterExpression[]{args[0]});

return curry.Compile();
}
}
}


式木を使って作っている。使い方はこんな感じ。
class Program
{
static void Main(string[] args)
{
Func<int,int,int,int> func = sum;
Func<int,Func<int,int,int>> curry = (Func<int,Func<int,int,int>>)func.Curry();

Console.WriteLine("{0}", curry(1)(2,3)); // 6


Test test = new Test();
test.z = 3.3;
Func<double,double,double> func2 = test.sum;
Func<double,Func<double,double>> curry2 = (Func<double,Func<double,double>>)func2.Curry();

Console.WriteLine("{0}", curry2(1.1)(2.2)); // 6.6
}

public static int sum(int x, int y, int z) {
return x+y+z;
}
}

public class Test {
public double z = 0;
public double sum(double x, double y) {
return x+y+z;
}
}



ちなみに、カリー化するメソッドの型が固定なら、めちゃくちゃ簡単に書ける。こんな感じ
public Func<int,Func<int,int>> Curry(Func<int,int,int> func) {
return (x)=>(y)=>func(x,y);
}


テーマ:プログラミング - ジャンル:コンピュータ
copyright © 2004-2006 SHOJI, Powered By FC2ブログ all rights reserved.
FC2ブログ