没有指针传递,写了个类来代替

Kation 2011-05-01 12:10:52
http://topic.csdn.net/u/20110226/00/821666c6-57bf-48f6-a6b9-fb1bca2be929.html
昨天突然发现该怎么解决我的这个问题,弄了个小时,OK了:


public sealed class Target
{
/// <summary>
/// 构造函数
/// </summary>
/// <param name="Assembly">程序集</param>
/// <param name="Target">对象</param>
/// <param name="Path">目标路径</param>
public Target(Assembly Assembly, string Target, string Path)
{
this.Target = Activator.CreateInstance(Assembly.GetType(Target));
string[] paths = Path.Split('.');
Method = paths[0];
_method = 0;
if (this.Target.GetType().GetProperty(Method) != null)
{
_method = 1;
}
if (this.Target.GetType().GetField(Method) != null)
{
_method = 2;
}
if (_method == 0)
throw new NullReferenceException("该对象不存在该属性");
if (paths.Count() > 1)
{
subpath = new Target(this, Path.Substring(Path.IndexOf('.')+1));
}
}

/// <summary>
/// 构造函数
/// </summary>
/// <param name="Target">对象</param>
/// <param name="Path">目标路径</param>
public Target(object Target, string Path)
{
this.Target = Target;
string[] paths = Path.Split('.');
Method = paths[0];
_method = 0;
if (Target.GetType().GetProperty(Method) != null)
{
_method = 1;
}
if (Target.GetType().GetField(Method) != null)
{
_method = 2;
}
if (_method == 0)
throw new NullReferenceException("该对象不存在该属性");
if (paths.Count() > 1)
{
subpath = new Target(this, Path.Substring(Path.IndexOf('.')+1));
}
}

private Target(MagicianTargetPath Parent, string Path)
{
parent = Parent;
Target = Parent.Value;
string[] paths = Path.Split('.');
Method = paths[0];
_method = 0;
if (Target.GetType().GetProperty(Method) != null)
{
_method = 1;
}
if (Target.GetType().GetField(Method) != null)
{
_method = 2;
}
if (_method == 0)
throw new NullReferenceException("该对象不存在该属性");
if (paths.Count() > 1)
{
subpath = new Target(this, Path.Substring(Path.IndexOf('.')+1));
}
}

private MagicianTargetPath parent;
private MagicianTargetPath subpath;
private int _method;
private object Target { get; set; }
private string Method { get; set; }


private object ThisValue
{
get
{
if (parent != null)
Target = parent.ThisValue;
if (_method == 1)
return Target.GetType().GetProperty(Method).GetValue(Target, null);
return Target.GetType().GetField(Method).GetValue(Target);
}
set
{
if (parent != null)
Target = parent.ThisValue;
if (_method == 1)
{
Target.GetType().GetProperty(Method).SetValue(Target, value, null);
}
else
{
Target.GetType().GetField(Method).SetValue(Target, value);
}
if (parent != null)
parent.ThisValue = Target;
}
}

/// <summary>
/// 对象值
/// </summary>
public object Value
{
get
{
if (subpath != null)
return subpath.Value;
return ThisValue;
}
set
{
if (subpath != null)
subpath.Value = value;
else
ThisValue = value;
}
}
}


这个是用来解决此类情景的:

如果你有个
class A
{
public Location Test{get;set;}
}

你想传递A.Test.X给其它过程,并且该过程之后还要获取或设置A.Test.X
如下:
class B
{
public B( ref int Test)
{
Test = 123;
}

private int test;

public void Test()
{
test = 345;
}
}


void xxx()
{
var a = new a();
var b = new b(a.Test.X);
b.Test();
}

如果希望这样后,a.Test.X变为345,是不行的。

而如果使用我这个类:
class B
{
public B(Target target)
{
this.target = target;
target.Value = 123;
}

private Target target;

public void Test()
{
target.Value = 345;
}
}


void xxx()
{
var a = new a();
var b = new b(new Target(a, "Test.X"));
b.Test();
}


这样,在实例化b的时候,a.Test.X变为123。
在调用b.Test()的时候,a.Test.X变为345。

就是在这种情况下使用了,有没有哪位高手可以优化哈~~~
...全文
182 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
Kation 2011-05-03
  • 打赏
  • 举报
回复
有没有高手有其它更简单的方法?
Kation 2011-05-01
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 caozhy 的回复:]
引用 4 楼 zip_xg 的回复:
引用 3 楼 caozhy 的回复:
看错了。。。

你尝试如下代码:

C# code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
cla……
[/Quote]
嗯,在构造函数里,检查是否存在Test.X,呵呵
至于安全性问题,我用的地方,不需要,呵呵

这个设计法则什么的,我不懂 - -,什么意思
threenewbee 2011-05-01
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 zip_xg 的回复:]
引用 3 楼 caozhy 的回复:
看错了。。。

你尝试如下代码:

C# code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
class Program
{
stati……
[/Quote]
Lambda表达式写起来只多两个标点。。。

而且反射有2个不好:
(1)反射没有编译器的类型检查,所以可能存在潜在的bug:你把Test.X写成了Text.X,编译器不会报错。另外当你重构代码的时候,重命名就很困难了。说严重点,还有可能有安全性问题。
(2)从OO设计法则来说,你的设计的职责是混乱的。
Kation 2011-05-01
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 caozhy 的回复:]
看错了。。。

你尝试如下代码:

C# code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
class Program
{
static vo……
[/Quote]

你这个和我当时的想法一样哈!!
读取一个Func<int>,写值一个Func<>(int)

我这个只需要传入一个值就行了,而且不需要创建对应Func
threenewbee 2011-05-01
  • 打赏
  • 举报
回复
看错了。。。

你尝试如下代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
var a = new A();
var b = new B(() => 345);
Console.WriteLine(b);
b.Test();
Console.WriteLine(b);
}
}

class A
{
public Location Test { get; set; }
}

class Location
{
public int X { get; set; }
}

class B
{
private Func<int> _SetTest;
public B(Func<int> SetTest)
{
_SetTest = SetTest;
test = 123;
}

private int test;

public void Test()
{
test = _SetTest();
}

public override string ToString()
{
return test.ToString();
}
}
}
threenewbee 2011-05-01
  • 打赏
  • 举报
回复
如果是值类型:

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

namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Container c = new Container();
Console.WriteLine(c);
MyClass mycalss = c.MyClassInstance;
mycalss.X = 20;
c.MyClassInstance = mycalss;
Console.WriteLine(c);
}
}

class Container
{
public MyClass MyClassInstance { get; set; }
public Container() { MyClassInstance = new MyClass() { X = 1 }; }
public override string ToString()
{
return MyClassInstance.X.ToString();
}
}

struct MyClass
{
public int X { get; set; }
}
}
threenewbee 2011-05-01
  • 打赏
  • 举报
回复
这和指针有什么关系。。。

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

namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Container c = new Container();
Console.WriteLine(c);
c.MyClassInstance.X = 20;
Console.WriteLine(c);
}
}

class Container
{
public MyClass MyClassInstance { get; set; }
public Container() { MyClassInstance = new MyClass() { X = 1 }; }
public override string ToString()
{
return MyClassInstance.X.ToString();
}
}

class MyClass
{
public int X { get; set; }
}
}


什么问题?

110,533

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧