是否可以将属性作为方法参数传递? [英] Is it possible to pass a property as a method parameter?

查看:61
本文介绍了是否可以将属性作为方法参数传递?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

亲爱的所有人
我是C#的初学者,并且正在与以下人员作斗争.

我尝试设计一个通用类,在该类中,方法应将值分配给参数.对于基本数据类型,使用ref或out参数很容易.但是我喜欢从另一个定义get/set方法的类传递一个属性.

问题是,我不知道是否有可能,如果可以,怎么办:(

提前谢谢您.
问候


代码片段:

a.)通用类

Dear all
I’m a beginner in c# and I’m fighting with the following.

I try to design a generic class, in which a method should assign a value to a parameter. For basic data types it is easy with a ref or out parameter. But I like to pass a property from another class which defines the get/set method.

The problem is, I do not have any idea whether it is possible and if yes how to do it :(

Thank you in advance.
Regards


Code fragments:

a.) The Generic class

public class MyGeneric<TWhatever, TResult>
{
  //
  // ******Here you find my problem******
  //
  // This method should assign the result to a property of another class
  public bool TryDoAnything(???here I like to pass "MyAny.AnyData" to assign
                            data as parameter result???)
  {
    ...
    if (success)
    {
      // In real the result comes from TWhatever
      result= new TResult();
    }
    return(success);
  }
}



b.)在应用程序中



b.) In the application

{
  MyGeneric<TheWhatever, PropertyClass> myGenericInUse= 
    new MyGeneric<TheWhatever, PropertyClass>();

  MainClass myMain= new MainClass();
  
  ...
  ...
  
  //
  // ******Here probably a have the next problem******
  //
  if (myGenericInUse.TryDoAnything(myMain.PropData))
  {
    // Do what is needed
  }
}



c.)具有必须由通用类设置的属性的类



c.) The class with the property which has to be set by the generic class

public class MainClass
{
  private PropertyClass propData;

  public PropertyClass PropData
  {
    get
    {
      return(propData);
    }
    set
    {
      propData= value;
    }
  }
}




d.)结果类(仅用于完整性)




d.) The result class (only for completness)

public class PropertyClass
{
}

推荐答案

您正在尝试混淆两个不相关的内容.

第一件事是传递参数.您可以将属性作为按值参数传递,因为无论如何都会从实际参数中复制一个值,并且编译器可以使用该属性来执行此操作.在契约中,outref参数传递方法处理对对象的引用,当然不能仅仅因为这根本不是对象而使用属性来完成,这是支持类似赋值的方法语法.

因此,只能将属性作为按值参数而不是outref传递.

顺便说一句,最好使用返回值代替outref并使用异常代替布尔值成功状态. Naerling的建议在这里非常好.实际上,几乎永远不应该使用成功状态,并且在任何情况下都不应使用错误条件,因为它破坏了异常的目的,并使代码更少,更难以管理.
使用泛型不会修改此语句中的内容.泛型或非泛型-无关紧要.

—SA
You are trying to mix up two unrelated things.

First thing is passing the parameters. You can pass a property as a by-value parameter, because a value is copied from the actual parameter anyway, and a compiler can do it with the property. In contract, out or ref parameter-passing method deal with the reference to the object, which of course cannot be done with the property just because this is not an object at all, this is the method backing the assignment-like syntax.

So, one can pass a property only as a by-value parameter, not out or ref.

By the way, it''s a good idea to use a return value instead of out or ref and exceptions instead of Boolean success status. Naerling''s advice is very good here. In fact, the success status almost never should be used, and error condition should not be used under any circumstances, as it defeats the purpose of exceptions and makes the code less, much less manageable.

Using generics does not modify a bit in this statement. Generic or non-generic — does not matter, whatsoever.

—SA


为什么在使用Generics时不能使用outref?
请参见以下示例.
Why would you not be able to use out or ref when using Generics?
See the following example.
class Program
{
    static void Main(string[] args)
    {
        int i = 10;
        GenericExample<int> ge = new GenericExample<int>();
        Console.WriteLine("The value of i is " + i.ToString());
        ge.SetSomeValue(ref i);
        Console.WriteLine("The value of i is " + i.ToString());
        Console.ReadKey();
    }		
}
    	
public class GenericExample<TResult>
{
    public bool SetSomeValue(ref TResult value)
    {
        value = Activator.CreateInstance<TResult>();
        return true;
    }
}

在控制台应用程序中运行此代码时,您会看到i在执行该函数之前为10,在执行该函数之后为0.您可以将i设置为所需的任何Property的值.
但是,为什么需要返回bool表示成功?为什么不简单地返回TResult的实例并在出现问题时抛出Exception(它减少了if-blocks的数量并允许适当的错误处理)?

如果您确实想设置Property(即在Property上调用set方法并传递在方法中以某种方式计算出的值),则可以使用Reflection,但我不建议这样做.这是您的操作方法.

When running this code in a console application you will see that i is 10 before executing the function and 0 after executing it. You can set i as the value of whatever Property you want.
However, why do you need to return a bool to indicate success? Why not simply return an instance of TResult and throw an Exception if something went wrong (it reduces the amount of if-blocks and allows for proper error handling)?

If you really wanted to set a Property (that is, invoke the set method on a Property and passing the value that was somehow calculated in your method) you could use Reflection, but I don''t recommend it. Here is how you would do it.

class Program
{
    static void Main(string[] args)
    {
        Person p = new Person();
        p.SomeProperty = 24;
        GenericExample<int> ge = new GenericExample<int>();
        Console.WriteLine("The value of SomeProperty is " + p.SomeProperty.ToString());
        ge.SetProperty(p, "SomeProperty");
        Console.WriteLine("The value of SomeProperty is " + p.SomeProperty.ToString());
        Console.ReadKey();
    }		
}

public class Person { public int SomeProperty {get; set;} }

public class GenericExample<TRresult>
{
    public bool SetProperty(object obj, string propertyName)
    {
        System.Reflection.PropertyInfo prop = obj.GetType().GetProperty(propertyName);
        prop.GetSetMethod().Invoke(obj, new object[] {Activator.CreateInstance<TResult>()});
        return true;
    }
}

您可以看到它的缺点.如果您更改SomeProperty的名称或拼写错误,则不会为错误提供设计时间支持.

You can see the downsides to this. If you would change the name of SomeProperty or misspell it you wouldn''t get design time support for the error.


我找到了一种方法,但我不太喜欢.
问候

a.)通用类
I found a way but I do not like it very much.
Regards

a.) The Generic class
public class MyGeneric<TWhatever,TResult>
{

  // Define an event type
  public delegate void PropertyAssign(TResult Value);

  // Pass a delegate (event?) to assign the result
  public bool TryDoAnything(PropertyAssign assignResult)
  {
    ...
    if (success)
    {
      // In real the result comes from TWhatever
      assignResult(new TResult());
    }
    return(success);
  }
}



b.)在应用程序中使用它



b.) Use it in the application

{
  MyGeneric<TheWhatever, MainClass> myGenericInUse= new 
    MyGeneric<TheWhatever, MainClass>();

  MainClass myMain= new MainClass();
  
  ...
  ...
  
  //
  // Here how to use it. A lot to write....
  //
  if (myGenericInUse.TryDoAnything(delegate(PropertyClass value)
                                   {myMain.PropData= value;}))
  {
    // Do what is needed
  }
}


这篇关于是否可以将属性作为方法参数传递?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆